在上一篇博客中说到了xml的DOM解析,虽然DOM解析比较好理解,但是如果xml文件的结构层次太深,在使用DOM解析就不太方便了。
一、SAX解析简介:
1、SAX解析是基于事件编程
简单来说就是当遇到某一个事件的时候就会触发一个对应的方法,满足事件编程3要素:
事件编程三要素:
- 事件源
- 这里的事件源值得就是写的xml文件
- 事件监听器
- 当遇到文档开始,触发方法startDocument(...)
- 当遇到开始标签,触发方法startElement(...)
- 当遇到文本内容,触发方法characters(...)
- 当遇到结束标签,触发方法endElement(...)
- 当遇到文档结束,触发方法endDocument(...)
- 注册事件监听器
- 自定义一个类,继承DefaultHandle ,覆盖里面的部分方法
2、SAX解析的特点:
读取一点,解析一点,节省空间(比如:当遇到开始标签,触发对应的方法之后,就会及时从内存中释放该节点)
3、SAX解析和DOM解析的区别:
原理上:前者读取一点,解析一点(节省内存);后者一次性加载整个xml文件,浪费空间,如果xml文件结构太深,就会产生OOM异常;
使用过程:前者只能去读,后者不仅能读,还能写,还能往返读
思想上:前者是面向时间编程,后者使用的是面向对象编程方式
二、简单使用案例:
1、SAX解析步骤:
- 自定义一个类继承DefaultHandler这个类,并覆盖里面的部分方法 ;
- 创建SAXParser对象 :
SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); // SAXParser类是一个抽象类,创建实例要通过工厂类实现
- 调用parser方法,读取对应的xml文件 :
public void parse(InputStream is, DefaultHandler dh) // 其中第一个参数为xml文件的InputStream对象,第二个参数为一个DefaultHandler对像
2、简单的使用案例:
还是以这个xml文件为例:
2.1 先简单使用一下DefaultHandler这个类
(覆写DefaultHandler这个类)
解析:
运行结果:(由于解析文本的时候空格,换行 也可以解析出来,所有会自己换行,这里运行结果比较长,就截图了一部分)
2.2 案例:使用SAX解析将原来的xml文件原样输出
class TestDefaultHandler extends DefaultHandler
{
//定义一个字符串,用来存储xml文件中的内容
private StringBuffer sb ;
public TestDefaultHandler() {
sb = new StringBuffer();
}
// 标签开始触发方法
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
//标签开始格式:<标签名 属性名=“属性值”>
//获取标签名称 String qName
sb.append("<").append(qName);
//遍历属性 Attributes attributes
for(int i=0; i<attributes.getLength(); i++)
{
sb.append(" ").append(attributes.getQName(i)).append(" = \'").append(attributes
.getValue(i)).append("\'");
}
sb.append(">");
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
// 遇到文本
sb.append(new String(ch, start, length));
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
// 标签结束格式:</标签名>
sb.append("<").append("/").append(qName).append(">");
}
@Override
public void endDocument() throws SAXException {
// dao文档结束的时候,整个xml文件内容已经走完了,打印sb
System.out.println(sb.toString());
}
}
public class Test {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
// 创建SAXParser对象
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
//解析
parser.parse(Test.class.getClassLoader().getResourceAsStream("contact.xml"), new
TestDefaultHandler());
}
}
运行结果: