对于较大的XML文件,dom4j提供了基于事件的SAX处理模型,我们可以在解析的过程中进行处理,而不用等解析完再处理。
知识点:
1. 在SAXReader类中,定义了一个addHandler()方法,当解析到参数path指定的路径时,将调用参数handler指定的处理器。
public voidaddHandler(String path,ElementHandler handler)
2. path是路径,ElementHandler是什么呢?一个接口,包含以下两个方法:
(1)public void onStart(ElementPath elementPath);
解析时一旦遇到元素的开始标签就会被调用。
(2)public void onEnd(ElementPath elementPath);
解析时一旦遇到元素的结束标签就会被调用。
3. ElementPath是什么呢?它也是一个接口,有以下几个主要方法。
(1) public voidaddHandler(String path,ElementHandler handler)
作用和SAXReader类中的addHandler方法相同。
(2)public voidremoveHandler(String path)
移除指定路径上的ElementHandler。
(3)publicvoid getPath()
得到当前节点路径。
(3)public Element getCurrent()
得到当前的元素。
OK,前期知识点到此止,代码走你!
要解析的xml文档:
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student sn="01">
<name>张三</name>
<age>12</age>
</student>
<student sn="02">
<name>李四</name>
<age>14</age>
</student>
</students>
JAVA代码:
package xml.pase;
import java.io.File;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.ElementHandler;
import org.dom4j.ElementPath;
import org.dom4j.io.SAXReader;
public class PaseXmlWithHandler {
public static void main(String[] args) throws DocumentException {
//这两行不用讲
SAXReader saxReader = new SAXReader();
File file = new File("student.xml");
//在/students/student添加一个ElementHandler实例,当走到/students/student这个路径时,调用ElementHandler里面的方法
saxReader.addHandler("/students/student", new StudentHandler());
saxReader.read(file);
}
private static class StudentHandler implements ElementHandler{
//要实现的两个方法,读到/students/student对应元素的开始标签时要调用的方法,就是这个<student>
public void onStart(ElementPath path) {
//得到当前路径下的元素
Element element = path.getCurrent();
System.out.println("找到一个学生,学号是:"+element.attributeValue("sn"));
//为student元素的子元素添加一个ElementHandler
path.addHandler("name", new NameHandler());
}
//要实现的两个方法,读到/students/student对应元素的结束标签时要调用的方法,就是这个</student>
public void onEnd(ElementPath path) {
//移除对子元素"name"的处理器ElementHandler
path.removeHandler("name");
}
}
private static class NameHandler implements ElementHandler{
//要实现的两个方法,读到/students/student/name对应元素的开始标签时要调用的方法,就是这个<name>
public void onStart(ElementPath path) {
//打印当前的路径,注意,此时不能打印内容,因为刚读到开始标签,读到结束标签时才能打印出
System.out.println("path:"+path.getPath());
}
//要实现的两个方法,读到/students/student/name对应元素的结束标签时要调用的方法,就是这个</name>
public void onEnd(ElementPath path) {
//得到当前路径下的元素
Element element = path.getCurrent();
//打印
System.out.println("元素名:"+element.getName()+" "+"文本内容:"+element.getText());
}
}
}
执行结果:
找到一个学生,学号是:01
path:/students/student/name
元素名:name 文本内容:张三
找到一个学生,学号是:02
path:/students/student/name
元素名:name 文本内容:李四