一、Sax解析
是从头到尾逐行逐个元素读取内容,修改较为不便,但适用于只读的大文档。
Sax采用事件驱动的方式解析文档。简单点说,如同在电影院看电影一样,从头到尾看一遍就完了,不能回退(Dom可来来回回读取)
在看电影的过程中,每遇到一个情节,一段泪水,一次擦肩,你都会调动大脑和神经去接收或处理这些信息
同样,在Sax的解析过程中,读取到文档开头、结尾,元素的开头和结尾都会触发一些回调方法,你可以在这些回调方法中进行相应事件处理
这四个方法是:startDocument() 、 endDocument()、 startElement()、 endElement
此外,光读取到节点处是不够的,我们还需要characters()方法来仔细处理元素内包含的内容
将这些回调方法集合起来,便形成了一个类,这个类也就是我们需要的解析器
一般从Main方法中读取文档,却在解析器中处理文档,这就是所谓的事件驱动解析方法(解释为转载)
------------------------------------------------------------------------------------------------------------------------------------------------------
解析器中的方法:
1.解析文档开头
1 @Override 2 public void startDocument() throws SAXException { 3 // TODO Auto-generated method stub 4 super.startDocument(); 5 }
2.解析开始标签
1 @Override 2 public void startElement(String uri, String localName, String qName, 3 Attributes attributes) throws SAXException { 4 // TODO Auto-generated method stub 5 super.startElement(uri, localName, qName, attributes); 6 }
3.解析内容
1 @Override 2 public void characters(char[] ch, int start, int length) 3 throws SAXException { 4 // TODO Auto-generated method stub 5 super.characters(ch, start, length); 6 }
4.解析结束标签
1 @Override 2 public void endElement(String uri, String localName, String qName) 3 throws SAXException { 4 // TODO Auto-generated method stub 5 super.endElement(uri, localName, qName); 6 }
5.解析文档结束
1 @Override 2 public void endDocument() throws SAXException { 3 // TODO Auto-generated method stub 4 super.endDocument(); 5 }
下面看一个Demo来实现解析一个xml文件
(1).xml文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <persons> 3 <person> 4 <name>张三</name> 5 <age>30</age> 6 <sex>男</sex> 7 </person> 8 9 <person> 10 <name>李四</name> 11 <age>32</age> 12 <sex>女</sex> 13 </person> 14 15 <person> 16 <name>王五</name> 17 <age>30</age> 18 <sex>男</sex> 19 </person> 20 </persons>
(2)解析器
1 package saxparser; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import org.xml.sax.Attributes; 7 import org.xml.sax.SAXException; 8 import org.xml.sax.helpers.DefaultHandler; 9 10 public class Myhandle extends DefaultHandler{ 11 //一个列表集合用来存放对象 12 List<Student> list = null; 13 Student stu = null; 14 //存放标签名称 15 String str = null; 16 //文件开始 17 @Override 18 public void startDocument() throws SAXException { 19 // TODO Auto-generated method stub 20 super.startDocument(); 21 System.out.println("文件解析开始"); 22 //准备工作,创建列表集合对象 23 list = new ArrayList<Student>(); 24 } 25 //标签开始 26 @Override 27 public void startElement(String uri, String localName, String qName, 28 Attributes attributes) throws SAXException { 29 // TODO Auto-generated method stub 30 super.startElement(uri, localName, qName, attributes); 31 str=qName; 32 //标签到这里说明有<person>数据了,需要创建一个Student对象存放解析出来的数据 33 if("person".equals(str)) 34 { 35 stu = new Student(); 36 // if(attributes!=null) 如果标签<person>里有属性的话 37 // { 38 // for(int i=0;i<attributes.getLength();i++) 39 // { 40 // //得到属性名 41 // String attrName = attributes.getQName(i); 42 // //得到属性值 43 // String attrValue = attributes.getValue(i); 44 // 45 // if("id".equals(attrName)) 46 // { 47 // stu.setId(attrValue); 48 // } 49 // } 50 // } 51 } 52 } 53 //内容解析 54 @Override 55 public void characters(char[] ch, int start, int length) 56 throws SAXException { 57 // TODO Auto-generated method stub 58 super.characters(ch, start, length); 59 //获得解析的标签内容 60 String s = new String(ch,start,length); 61 if("name".equals(str)) 62 { 63 stu.setName(s); 64 } 65 else if("age".equals(str)) 66 { 67 stu.setAge(Integer.parseInt(s)); 68 } 69 else if("id".equals(str)) 70 { 71 stu.setAge(Integer.parseInt(s)); 72 } 73 } 74 //结束标签解析 75 @Override 76 public void endElement(String uri, String localName, String qName) 77 throws SAXException { 78 // TODO Auto-generated method stub 79 super.endElement(uri, localName, qName); 80 //注意这里,存放标签名字的str字符串必须要置空,=null or ="" 81 str=null; 82 if("person".equals(qName)) 83 { 84 list.add(stu); 85 } 86 } 87 //结束文件解析 88 @Override 89 public void endDocument() throws SAXException { 90 // TODO Auto-generated method stub 91 super.endDocument(); 92 System.out.println("文件解析结束"); 93 } 94 95 public List<Student> list(){ 96 return list;//返回列表集合 97 } 98 } 99 100 Myhandle.java 解析器
(3)测试类
1 package saxparser; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.util.ArrayList; 6 import java.util.List; 7 8 import javax.xml.parsers.ParserConfigurationException; 9 import javax.xml.parsers.SAXParser; 10 import javax.xml.parsers.SAXParserFactory; 11 12 import org.xml.sax.SAXException; 13 14 public class Text { 15 public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException { 16 //创建解析的工厂类对象 17 SAXParserFactory factory = SAXParserFactory.newInstance(); 18 //创建解析器对象 19 SAXParser parser = factory.newSAXParser(); 20 21 File f= new File("user.xml"); 22 //解析器去读取xml文件并去调用handle里边的函数 23 Myhandle handle = new Myhandle(); 24 parser.parse(f, handle); 25 //获得存放Student对象的集合 26 List<Student> list = handle.list; 27 //遍历集合 28 for(int i=0;i<list.size();i++) 29 { 30 System.out.println(list.get(i)); 31 } 32 33 } 34 }
(4).对象类
1 package saxparser; 2 3 public class Student { 4 private int id; 5 private String name ; 6 private int age; 7 public Student() { 8 super(); 9 // TODO Auto-generated constructor stub 10 } 11 public Student(int id, String name, int age) { 12 super(); 13 this.id = id; 14 this.name = name; 15 this.age = age; 16 } 17 public int getId() { 18 return id; 19 } 20 public void setId(int id) { 21 this.id = id; 22 } 23 public String getName() { 24 return name; 25 } 26 public void setName(String name) { 27 this.name = name; 28 } 29 public int getAge() { 30 return age; 31 } 32 public void setAge(int age) { 33 this.age = age; 34 } 35 @Override 36 public String toString() { 37 return "Student [id=" + id + ", name=" + name + ", age=" + age + "]"; 38 } 39 40 41 }
(5)控制台输出信息
1 文件解析开始 2 文件解析结束 3 Student [id=0, name=张三, age=30] 4 Student [id=0, name=李四, age=32] 5 Student [id=0, name=王五, age=30]