这一节,介绍XML文档的另一种解析方式,SAX。
之前介绍过,DOM解析是一次性把xml文档加载进内存,然后在内存中构建Document树。对内存要求比较要。缺点: 不适合读取大容量的xml文件,容易导致内存溢出。SAX解析是加载一点,读取一点,处理一点。对内存要求比较低。
SAX解析工具是由Sun公司提供的,内置在jdk中,就不需要引入其他的jar包了。
下面来看一下SAX解析在Java代码中的使用:
SAX解析要自己写处理程序,通过继承DefaultHandler类。
/**
* 第一个SAX读取xml文件程序
* @author YIPENG
*
*/
public class Demo1 {
public static void main(String[] args) throws Exception{
//1.创建SAXParser对象
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
//2.调用parse方法
/**
* 参数一: xml文档
* 参数二: DefaultHandler的子类
*/
parser.parse(new File("./src/contact.xml"), new MyDefaultHandler());
}
}
/**
* SAX处理程序(如何解析xml文档)
* @author YIPENG
*
*/
public class MyDefaultHandler extends DefaultHandler {
/**
* 开始文档时调用
*/
@Override
public void startDocument() throws SAXException {
System.out.println("MyDefaultHandler.startDocument()");
}
/**
* 开始标签时调用
* @param qName: 表示开始标签的标签名
* @param attributes: 表示开始标签内包含的属性列表
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
System.out.println("MyDefaultHandler.startElement()-->"+qName);
}
/**
* 结束标签时调用
* @param qName: 结束标签的标签名称
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.println("MyDefaultHandler.endElement()-->"+qName);
}
/**
* 读到文本内容的时调用
* @param ch: 表示当前读完的所有文本内容
* @param start: 表示当前文本内容的开始位置
* @param length: 表示当前文本内容的长度
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
//得到当前文本内容
String content = new String(ch,start,length);
System.out.println("MyDefaultHandler.characters()-->"+content);
}
/**
* 结束文档时调用
*/
@Override
public void endDocument() throws SAXException {
System.out.println("MyDefaultHandler.endDocument()");
}
}
/**
* 读取contact.xml文件,完整输出文档内容
* @author YIPENG
*
*/
public class Demo2 {
public static void main(String[] args)throws Exception {
//1.创建SAXParser
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
//2.读取xml文件
MyDefaultHandler2 handler = new MyDefaultHandler2();
parser.parse(new File("./src/contact.xml"), handler);
String content = handler.getContent();
System.out.println(content);
}
}
/**
* SAX处理器程序
* @author YIPENG
*/
public class MyDefaultHandler2 extends DefaultHandler {
//存储xml文档信息
private StringBuffer sb = new StringBuffer();
//获取xml信息
public String getContent(){
return sb.toString();
}
/**
* 开始标签
*/
@Override
public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {
sb.append("<"+qName);
//判断是否有属性
if(attributes!=null){
for(int i=0;i<attributes.getLength();i++){
//得到属性名称
String attrName = attributes.getQName(i);
//得到属性值
String attrValue = attributes.getValue(i);
sb.append(" "+attrName+"=\""+attrValue+"\"");
}
}
sb.append(">");
}
/**
* 文本内容
*/
@Override
public void characters(char[] ch, int start, int length)throws SAXException {
//得到当前读取的文本
String content = new String(ch,start,length);
sb.append(content);
}
/**
* 结束标签
*/
@Override
public void endElement(String uri, String localName, String qName)throws SAXException {
sb.append("</"+qName+">");
}
}
最后,对DOM解析和SAX解析做一下对比:
1、DOM解析一次性加载xml文档,不适合大容量的文件读取;SAX解析加载一点,读取一点,处理一点。适合大容量文件的读取。
2、DOM解析可以任意进行增删改查;SAX解析只能读取。
3、DOM解析任意读取任何位置的数据,甚至往回读;SAX解析只能从上往下,按顺序读取,不能往回读。
4、DOM解析面向对象的编程方法(Node,Element,Attribute),Java开发者编码比较简单;SAX解析基于事件的编程方法,java开发编码相对复杂。