DOM4J解析XML文档学习目标掌握dom4j的概念和特点掌握dom4j的常用接口熟练掌握使用dom4j解析XML文档熟练掌握使用访问者模式遍历XML文档掌握使用dom4j创建和修改XML文档dom4j概述JAXP虽然在DOM和SAX解析机制上进行了一定的抽象,但是对XML解析非常繁琐,编程代码冗长,可读性不高。因此在JAVA领域出现了两个开源的XML解析器:dom4j和JDOM。dom4j的开发者说:使用dom4j来解析XML文档,无须参考任何图书,只要有基本的DOM概念,那么对着dom4j的API文档即可使用dom4j解析。dom4j概述dom4j是一套开源的XML解析工具,完全支持DOM、SAX和JAXP机制。与它们相比,dom4j更为简单易用,因此实际项目中往往选择dom4j作为XML解析器。dom4j没有提供其他语言版本,只提供JAVA语言版本。dom4j的封装和优势dom4j在很大程序上简化了XML的处理方式。从表面上看,dom4j有点类似于DOM解析机制,也将XML文档转换为一棵结构化树(dom4j树),但dom4j树的处理方式比DOM树更为简单。由于dom4j如此优秀,很多优秀的开源项目都采用dom4j作为XML解析器,在实际的开发过程中,它通常是首选。面向接口编程它的实质是以其他XML解析器为基础,dom4j采用面向接口编程的方式来处理XML文档解析,这就允许dom4j的底层可以在不同的解析机制之间自由切换。支持多种解析机制•DOMReader:它负责根据W3C的DOM树创建dom4j树•SAXReader:它基于SAX解析机制来分析一份XML文档,并将其转换为dom4j树•XPP3Reader:其底层需要依赖于XMLPulllParser3.x来解析XML文档,并将其转换为dom4j树•XPPReader:其底层需要依赖于XMLPulllParser2.x来解析XML文档,并将其转换为dom4j树listbook疯狂XML讲义/bookgame扫雷/gamesport乒乓球/sport/list//获取list元素下的所有子元素NodeListitemList=list.getChildNodes();//遍历每个子元素for(intI=0;IitemList.getLength();I++){System.out.println(itemList.item(j).getTextContent().trim());}在获取list…/节点之后,如果希望获取它包含的3个子节点的数据,需要使用如下代码这种处理方式很是繁琐,list元素调用getChildNodes()方法返回该元素的所有子节点,而不是所有的子元素,这使得程序的处理过程非常繁琐。//获取list元素下的所有子元素ListitemList=list.elements();//遍历每个子元素for(intI=0;IitemList.getLength();I++){Elementele=(Element)itemList.get(I);System.out.println(els.getText());}list元素调用elements()方法返回该元素的所有子元素(包括子节点和该节点的文本内容),dom4j处理方式更接近平常自然的思维。下载和安装dom4j登录dom4j的官方站点下载最新版本dom4j1.6.1下载完成后得到dom4j1.6.1.zip,将其解压缩可得到如下目录结构•docs:该目录下存放了dom4j的说明文件和API文档•lib:该目录下存放了dom4j编译和运行所依赖的第三方类库•Src:该目录下存放了dom4j项目的所有源文件•xdocs:该目录存放dom4j的一些相关文档,是XML格式•xml:该目录下存放了dom4j提供了一些简单的范例xml文档•dom4j-1.6.1.jar:dom4j的核心JAR包将dom4j-1.6.1.jar添加到系统CLASSPATH环境变量中Dom4j常用的API【重点掌握】NodeCharacterDataProcessingInstructionCDATATextCommentAttributeCloneableDocumentTypeBranchDocumentElementDom4j的API接口简单说明Node它是dom4j树中所有节点的跟接口Branch它代表能包含子节点的节点Element它代表XML元素Doucment它代表XML文档根Attribute它代表XML元素属性DocumentType它代表XML文档中的DOCTYPE声明ProceesingInstruction它代表XML文档中的处理指令CharacterData它是所有文本元素的父接口CDATA它代表XML文档中的CDATA段Text它代表XML文档里的文本内容Comment它代表XML文档里的注释内容除此之外,dom4j为解析xml文档还提供了DOMReader、SaxReader、XPP3Reader和XPPReader4个解析器,负责将不同形式的XML文档解析成dom4j树。对应地,dom4j也提供了如下几个Writer:DOMWriter:该输出工具类负责将dom4j树转换成为W3C的DOM树SAXWriter:该输出工具类负责将dom4j树输出给SAX的ContendHandler处理XMLWriter:该工具类将dom4j树转换成对应的XML文档,并可输出到指定流中除此之外,如果程序需要创建一份新Document,dom4j还提供了如下2个工具类DocumentFactory:该工具提供createDocument()方法用于创建Document对象DocumentHelper该工具提供了大量静态方法用于创建XML文档各组成部分使用dom4j解析XML文档【重点掌握】使用dom4j解析XML文档的过程是这样的,首先是将XML文档转换成dom4j树之后,使用一致的编程模型来处理XML文档。我们可以采用递归方法来获取整份XML文档里包含的信息。publicclassDom4jRead{publicstaticvoidmain(String[]args)throwsException{//使用SAXReader来解析XML文档SAXReaderreader=newSAXReader();Documentdoc=reader.read(newFile(book.xml));Elementroot=doc.getRootElement();parse(root);}publicstaticvoidparse(Elementele){//处理当前元素包含的所有属性parseAttribute(ele);//获取当前元素包含的所有子元素Listel=ele.elements();//遍历每个子元素for(Objecte:el){Elementelement=(Element)e;//如果该元素的内容不是只包含字符串if(!element.isTextOnly()){parse(element);}else{//处理当前元素的全部属性parseAttribute(element);//获取当前元素的内容System.out.println(element.getQName().getName()+---+element.getText());}}}//定义一个方法处理指定元素的所有属性publicstaticvoidparseAttribute(Elementele){//获取Element元素的所有属性ListattList=ele.attributes();//遍历Element元素每个属性for(Objecte:attList){Attributeattr=(Attribute)e;//访问当前元素的每个属性的属性值System.out.println(ele.getQName().getName()+元素的+attr.getQName().getName()+属性值为:+attr.getValue());}}使用访问者遍历XML文档【重点掌握】dom4j的Node接口中定义了一个accept(Visitorvistor)方法,由于该方法是在Node接口中定义的,因此dom4j树中的任何节点都可以调用该方法,调用该方法时传入的Visitor对象将负责处理该节点及其所有子节点的信息。Visitor接口和VisitorSupport类的关系就像事件监听接口和事件适配器一样。VisitorSupport类实现了Visitor接口,并为每个方法提供了空实现。当开发者通过继承VisitorSupport类来实现自己的Visitor时就可以只重写自己关系的方法,从而避免重写Visitor接口里的所有方法。Vistor接口的方法简单说明visit(Attributenode)当Visitor对象访问属性节点时将回调该方法visit(CDATAnode)当Visitor对象访问CDATA片段时将回调该方法visit(Commentnode)当Visitor对象访问注释节点时将回调该方法visit(Documentdocument)当Visitor对象访问文档根节点时将回调该方法visit(DocumentTypedocumentType)当Visitor对象访问DTD内容将回调该方法visit(Elementnode)当Visitor对象访问元素节点将回调该方法visit(Entitynode)当Visitor对象访问Entity节点将回调该方法visit(Namespacenamespace)当Visitor对象访问命名空间时回调该方法visit(ProcessingInstructionnode)当Visitor对象访问处理指令时回调该方法visit(Textnode)当Visitor对象访问文档内容时将回调该方法classYeekuVistorextendsVisitorSupport{privateStringcurrentElement;//保存当前正在处理的节点//当Visitor访问元素时回调该方法publicvoidvisit(Elementnode){if(node.isTextOnly())//如果节点内容全部是文本{System.out.println(node.getName()+元素的值是:+node.getText());}currentElement=node.getName();}//当Visitor访问属性时回调该方法publicvoidvisit(Attributenode){System.out.println(currentElement+元素的+node.getName()+属性的值是:+node.getText());}//当Visitor访问处理指令时回调该方法publicvoidvisit(ProcessingInstructionnode){System.out.println(处理指令+node.getTarget()+的内容是:+node.getText());}}publicclassVisitorRead{publicstaticvoidmain(String[]args)throwsException{SAXReaderreader=newSAXReader();Documentdoc=reader.read(newFile(book.xml));//使用访问者模式来访问XML文档doc.accept(newYeekuVistor());}}Visitor里只实现visit(Elementnode)、visit(Attributenode)和visit(ProcessingInstructionnode)3个方法,这意味着该Vistor只处理XML文档里的元素,属性和处理指令。注