上节实现了输出XML文档,这一节,将对输出的XML文档进行访问解析。
在dom4j中,有很多种方式可以实现这个功能,但这一节只使用访问者(visitor)模式来进行操作。
访问者模式用来处理对象树结构,树中的每一个节点对象可以接受一个访问者对象,节点对象向访问都传递自身,而访问者对象调用节点对象的操作。
书上的话,尼玛太抽象了,先放一下,后面结合代码来理解。
在dom4j中,有一个Visitor接口,它根据不同类型的节点,定义了几个重载的visit()方法。例如:
publicvoid visit(Element node);
publicvoid visit(Attribute node);
……
我们需要实现这个接口,然后调用Node接口中的accept(Visitor visitor)方法,上面的visit()方法是用来被重写的,重写时可以调用参数node的方法。
package xml.pase;
import java.io.File;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.ProcessingInstruction;
import org.dom4j.VisitorSupport;
import org.dom4j.io.SAXReader;
public class ParseXmlWithVisitor {
public static void main(String[] args) throws DocumentException {
SAXReader saxReader = new SAXReader();
File file = new File("student.xml");
//用saxReader读取xml文件,创建dom4j文档树
Document doc = saxReader.read(file);
//接收一个visitor对象,开始对xml文件的解析,遍历每个节点,每个节点调用accept(Visitor visitor)方法时,调用visitor的visit(this)方法
doc.accept(new MyVisitor());
}
//VisitorSupport实现了Visitor接口,继承它然后重写visit()方法
private static class MyVisitor extends VisitorSupport{
//访问元素节点
public void visit(Element node){
//元素节点只含文本
if(node.isTextOnly()){
System.out.println("元素名:"+node.getName()+" "+"文本:"+node.getText());
System.out.println("---------------------");
}else{
System.out.println("元素名:"+node.getName());
System.out.println("---------------------");
}
}
//访问属性节点
public void visit(Attribute node){
System.out.println("属性:"+node.getName()+" "+node.getValue());
System.out.println("---------------------");
}
//访问处理指令节点
public void visit(ProcessingInstruction node){
System.out.println("处理指令:"+node.getTarget()+" "+node.getText());
System.out.println("---------------------");
}
}
}
结果:
元素名:students
---------------------
元素名:student
---------------------
属性:sn 01
---------------------
元素名:name 文本:张三
---------------------
元素名:age 文本:12
---------------------
元素名:student
---------------------
属性:sn 02
---------------------
元素名:name 文本:李四
---------------------
元素名:age 文本:14
---------------------
好了,结果出来了,现在再理解一下这句话:
树中的每一个节点对象可以接受一个访问者对象,节点对象向访问者传递自身,而访问者对象调用节点对象的操作。