一、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]