SAX解析
SAX(simple API for XML)是一种XML解析的替代方法。相比于DOM,SAX是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。通过解析工厂对象 和ContentHandler 接口对文档进行解析。
解析工厂对象SAXParseFactory 用于SAX解析 是一种基于事件流的方式进行解析,只能对文档从头到尾 进行解析无法随机访问xml文档,以及对文档进行添加 修改 和删除操作。
SAX解析中中有四种处理事件的接口ContentHandler(主要用到的接口),DTDHandler, EntityResolver 和 ErrorHandler。
DOM解析和SAX解析的区别:
Dom 是将文档读取内存中,把文档看成是一倒挂的树形结构,支持对文档随机访问,以及增删改的相关操作。
SAX 基于事件流 事件流来自于ContentHandler接口的实现,回调的机制 不支持对文档的随机访问和增删改的操作。
接下来针对该xml文件进行解析:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<student id="001">
<name>aa</name>
<age>18</age>
</student>
<student id="002">
<name>bb</name>
<age>28</age>
</student>
<student id="003">
<name>cc</name>
<age>38</age>
</student>
</configuration>
SAX解析:
(1)创建事件处理程序(也就是编写ContentHandler的实现类)
public class MyHandler implements ContentHandler {
private static final String STUDENT_ELEMENT = "student";
private static final String NAME_ELEMENT = "name";
private static final String AGE_ELEMENT = "age";
private String currentData = "";//用于接收xml文件中的文本节点
private Attributes attr = null;//用于接收xml文件中的属性节点
/**
* 当其他某一个调用事件发生时 ,会先调用该方法来对文件进行定位
*/
@Override
public void setDocumentLocator(Locator locator) {
}
/**
*当文件解析开始,该方法被调用,该方法只调用一次
*/
@Override
public void startDocument() throws SAXException {
System.out.println("-----解析开始------");
}
/**
*当文件解析结束,该方法被调用,该方法只调用一次
*/
@Override
public void endDocument() throws SAXException {
System.out.println("-----解析结束------");
}
/**
* 开始进行前缀映射-命名空间 该方法被调用
*/
@Override
public void startPrefixMapping(String prefix, String uri) throws SAXException {
}
@Override
public void endPrefixMapping(String prefix) throws SAXException {
}
/**
* 在解析Element节点开始时该方法被调用
* uri 服务器的路径 没有可以为null
* localName 主机名
* qName 标签节点的名字
* atts 解析element元素的时候的属性节点
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
attr = atts;
if(qName.equals(STUDENT_ELEMENT)){
String value = attr.getValue("id");
if(value != null){
System.out.println("id:" + value);
}
System.out.println(qName + currentData);
}
}
/**
* 在解析Element节点结束时该方法被调用
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if(qName.equals(NAME_ELEMENT)){
System.out.println(qName + ":" + currentData);
}
if(qName.equals(AGE_ELEMENT)){
System.out.println(qName + ":" + currentData);
}
}
/**
*用于处理字符信息的方法
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
currentData = new String(ch, start, length);
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
}
@Override
public void processingInstruction(String target, String data) throws SAXException {
}
@Override
public void skippedEntity(String name) throws SAXException {
}
}
(2)创建SAX解析器
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
//SAXParserFactory来创建一个SAXParserFactory实例
SAXParserFactory factory = SAXParserFactory.newInstance();
//根据SAXParserFactory实例来创建SAXParser
SAXParser parser = factory.newSAXParser();
//通过SAXParser获取SAXReader
XMLReader reader = parser.getXMLReader();
//XMLReader 加载XML,然后解析XML
reader.setContentHandler( new MyHandler() );
reader.parse("test.xml");
}
效果如下: