学了DOC解析后我就在想老师为什么还要讲SAX解析呢?原来他们的解析方式是存在差异的,如下表所示:
DOC解析 | SAX解析 |
在内存中创建文档树,不适合处理大型XML文档 | 顺序读入文档并产生相应事件,可以处理大型的XML文档 |
可以随意访问文档的任何部分,没有次数限制 | 只能对文档按顺序解析一遍,不能任意访问 |
可以任意修改文档树,从而修改XML文档 | 只能读取XML文档,而不能修改XML文档 |
易于理解易于开发 | 开发上比较复杂,需要自己来实现事件处理器 |
已经在DOM基础之上创建好了文档树 | 对开发人员而言更灵活,可以用SAX创建自己的XML对象模型 |
详细对比:
如上图所示:
前两步的方式是一样的,只不过是代码不同而已,都是先创建解析器对象工厂,然后创建解析器对象
唯一不同的是第三步DOM是直接DOM树解析(然后再通过子节点解析XML),而SAX必须要通过创建事件处理器来解析,所以SAX解析总的来说比较复杂,事件处理器代码如下:
package cjl.sax;
import java.util.ArrayList;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* sax事件处理器
*
* @author kowloon
*
*/
public class MyDefaultHandler extends DefaultHandler {
ArrayList<Student> slist;
String strValue;
Student stu;
@Override
public void startDocument() throws SAXException {
slist = new ArrayList<Student>();
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (qName.equals("stu")) {
// 创建学生对象
stu = new Student();
// 获得该节点的属性
String num = attributes.getValue("num");
stu.num = Integer.parseInt(num);
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (qName.equals("name")) {
stu.name = strValue;
}
if (qName.equals("sex")) {
stu.sex = strValue;
}
if (qName.equals("cla")) {
stu.cla = strValue;
}
if (qName.equals("stu")) {
slist.add(stu);
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
strValue = new String(ch, start, length);
System.out.println("解析文本:" + strValue);
}
@Override
public void endDocument() throws SAXException {
System.out.println("解析完成-----------------");
// 遍历队列,取出学生对象
for (Student s : slist) {
System.out.println(s.toString());
}
}
}
所以建议小的XML文档还是用DOC解析,因为DOC是解析整篇文档,易于修改
大的文档还是用SAX解析,因为SAX是读一点扔一点,易于读取,再说大的XML文档
DOC也不好解析占内存,解析速度极慢。切记大的文档不要用DOC去解析。