`

DOM4J介绍与代码示例

 
阅读更多
DOM4Jdom4j.org出品的一个开源XML解析包。Dom4j是一个易用的、开源的库,用于XMLXPathXSLT。它应用于Java平台,采用了Java集合框架并完全支持DOMSAXJAXP
DOM4J下载jar包:http://downloads.sourceforge.net/dom4j/dom4j-1.6.1.jar
JAXEN(对XPath的支持):http://dist.codehaus.org/jaxen/distributions/jaxen-1.1.1.zip
其中用到了2个包:分别是dom4j-1.6.1.jar和jaxen.jar

注:在创建xml时只需要dom4j包就可以了,而在解析修改xml的时候必须有jaxen包才行,否则会报错。
错误描述:Exception in thread "main" java.lang.NoClassDefFoundError: org/jaxen/JaxenException
at org.dom4j.DocumentFactory.createXPath(DocumentFactory.java:230)
at org.dom4j.tree.AbstractNode.createXPath(AbstractNode.java:207)
at org.dom4j.tree.AbstractNode.selectNodes(AbstractNode.java:164)
at com.elecpaper.buss.action.dom4jUpdate.main(dom4jUpdate.java:24)
1.DOM4J主要接口
DOM4J主要接口都在org.dom4j这个包里定义。
 

 
-Node为所有的dom4jXML节点定义了多态行为;
 
-Branch为能够包含子节点的节点如XML元素(Element)和文档(Docuemnts)定义了一个公共的行为;
|-Element 定义XML 元素;
|-Document定义了XML文档;
 
-DocumentType 定义XML DOCTYPE声明;
-Entity定义 XML entity
-Attribute定义了XML的属性;
-ProcessingInstruction 定义 XML 处理指令;
 
-CharacterData是一个标识借口,标识基于字符的节点。如CDATAComment, Text
|- CDATA 定义了XML CDATA 区域;
|-Text 定义XML 文本节点;
|- Comment 定义了XML注释的行为;
2.创建XML文档
示例xmlstudents.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="students.xsl"?>
<students>
    <!--A Student Catalog-->
    <student sn="01">
       <name>sam</name>
       <age>18</age>
    </student>
    <student sn="02">
       <name>lin</name>
       <age>20</age>
    </student>
</students>
 下面是用dom4j创建上述文档,通过两种方式创建,一种是调用dom4j提供的方法,一种是通过字符串转换。
XmlGen.java
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
 
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.XMLWriter;
 
public class XmlGen {
    public Document generateDocumentByMethod() {
       //文档助手创建文档实例
       Document document = DocumentHelper.createDocument();
       // ProcessingInstruction 处理指令
       Map<String, String> inMap = new HashMap<String, String>();
       inMap.put("type", "text/xsl");
       inMap.put("href", "students.xsl");
       document.addProcessingInstruction("xml-stylesheet", inMap);
       // root element 添加根节点
       Element studentsElement = document.addElement("students");
       studentsElement.addComment("An Student Catalog");
       // son element 添加子节点
       Element stuElement = studentsElement.addElement("student");
       stuElement.addAttribute("sn", "01");
       Element nameElement = stuElement.addElement("name");
       nameElement.setText("sam");
       Element ageElement = stuElement.addElement("age");
       ageElement.setText("18");
       // son element
       Element anotherStuElement = studentsElement.addElement("student");
       //在子节点中加入属性
       anotherStuElement.addAttribute("sn", "02");
       Element anotherNameElement = anotherStuElement.addElement("name");
       anotherNameElement.setText("lin");
       Element anotherAgeElement = anotherStuElement.addElement("age");
       anotherAgeElement.setText("20");
 
       return document;
    }
 
    public Document generateDocumentByString() {
       String text = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
              "<?xml-stylesheet type=\"text/xsl\" href=\"students.xsl\"?>" +
              "<students><!--An Student Catalog-->   <student sn=\"01\">" +
              "<name>sam</name><age>18</age></student><student sn=\"02\">" +
              "<name>lin</name><age>20</age></student></students>";
       Document document = null;
       try {
           document = DocumentHelper.parseText(text);
       } catch (DocumentException e) {
           e.printStackTrace();
       }
       return document;
    }
 
    public void saveDocument(Document document, File outputXml) {
       try {
           // 美化格式
           OutputFormat format = OutputFormat.createPrettyPrint();
           /*// 缩减格式
           OutputFormat format = OutputFormat.createCompactFormat();*/
           /*// 指定XML编码
            format.setEncoding("GBK");*/
           XMLWriter output = new XMLWriter(new FileWriter(outputXml), format);
           output.write(document);
           output.close();
       } catch (IOException e) {
           System.out.println(e.getMessage());
       }
    }
 
    public static void main(String[] argv) {
       XmlGen dom4j = new XmlGen();
       Document document = null;
       // document=dom4j.generateDocumentByMethod();
       document = dom4j.generateDocumentByString();
       dom4j.saveDocument(document, new File("output.xml"));
    }
}
 
方法generateDocumentByMethod()通过调用方法构建xml文档:
1.使用DocumentHelper得到Document实例
Document document = DocumentHelper.createDocument();
2.创建Processing Instruction
document.addProcessingInstruction("xml-stylesheet", inMap);
3.创建元素Element
Element studentsElement = document.addElement("students");
4.为元素添加注释Comment
studentsElement.addComment("An Student Catalog");
5.为元素添加属性
studentsElement.addComment("An Student Catalog");
6.为元素添加文本值Text
ageElement.setText("18");
 
方法generateDocumentByString()通过字符串转换直接构建xml文档,使用DocumentHelper.parseText()来实现.
document = DocumentHelper.parseText(text);
 
方法saveDocument(Document document, File outputXml)将文档输出到文件保存,可指定字符编码,可指定格式化输出。
3.修改XML文档
这里使用xpath来定位待修改的元素和属性,需要jaxen的支持。
示例中将students-gen.xml的第一个student元素的sn属性改为001,其子元素name内容改为jeff
XmlMod.java
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
 
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
 
public class XmlMod {
    public void modifyDocument(File inputXml) {
       try {
           //得到解析器
           SAXReader saxReader = new SAXReader();
           //读取xml
           Document document = saxReader.read(inputXml);
           //查找students节点下的子节点student的属性为sn的元素
           List list = document.selectNodes("//students/student/@sn");
           Iterator iter = list.iterator();
           while (iter.hasNext()) {
              Attribute attribute = (Attribute) iter.next();
              //把01换成001
              if (attribute.getValue().equals("01"))
                  attribute.setValue("001");
           }
 
           list = document.selectNodes("//students/student");
           iter = list.iterator();
           while (iter.hasNext()) {
              Element element = (Element) iter.next();
              Iterator iterator = element.elementIterator("name");
              while (iterator.hasNext()) {
                  Element nameElement = (Element) iterator.next();
                  if (nameElement.getText().equals("sam"))
                     nameElement.setText("jeff");
              }
           }
 
           XMLWriter output = new XMLWriter(new FileWriter(new File(
                  "students-modified.xml")));
           output.write(document);
           output.close();
       }
 
       catch (DocumentException e) {
           System.out.println(e.getMessage());
       } catch (IOException e) {
           System.out.println(e.getMessage());
       }
    }
 
    public static void main(String[] argv) {
       XmlMod dom4jParser = new XmlMod();
       dom4jParser.modifyDocument(new File("students-gen.xml"));
    }
}
 
1.使用File定位文件资源,并基于此获得Document实例
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(inputXml);
2.Document实例的selectNodes方法可以传入xpath,并返回一个List实例,基于此使用迭代器,完成特定的应用
List list = document.selectNodes("//students/student/@sn");
4.遍历XML文档
这里提供两种遍历方法,一种是基于迭代的遍历,一种是基于Visitor模式的遍历。
XmlTra.java
import java.io.File;
import java.util.Iterator;
 
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 XmlTra {
    private File inputXml;
 
    public XmlTra(File inputXml) {
       this.inputXml = inputXml;
    }
 
    public Document getDocument() {
       SAXReader saxReader = new SAXReader();
       Document document = null;
       try {
           document = saxReader.read(inputXml);
       } catch (DocumentException e) {
           e.printStackTrace();
       }
       return document;
    }
 
    public Element getRootElement() {
       return getDocument().getRootElement();
    }
 
    public void traversalDocumentByIterator() {
       Element root = getRootElement();
       // 枚举根节点下所有子节点
       for (Iterator ie = root.elementIterator(); ie.hasNext();) {
           System.out.println("======");
           Element element = (Element) ie.next();
           System.out.println(element.getName());
 
           // 枚举属性
           for (Iterator ia = element.attributeIterator(); ia.hasNext();) {
              Attribute attribute = (Attribute) ia.next();
              System.out.println(attribute.getName() + ":"
                     + attribute.getData());
           }
           // 枚举当前节点下所有子节点
           for (Iterator ieson = element.elementIterator(); ieson.hasNext();) {
              Element elementSon = (Element) ieson.next();
              System.out.println(elementSon.getName() + ":"
                     + elementSon.getText());
           }
       }
    }
 
    public void traversalDocumentByVisitor() {
       getDocument().accept(new MyVisitor());
    }
 
    /**
     * 定义自己的访问者类
     */
    private static class MyVisitor extends VisitorSupport {
       /**
        * 对于属性节点,打印属性的名字和值
        */
       public void visit(Attribute node) {
           System.out.println("attribute : " + node.getName() + " = "
                  + node.getValue());
       }
 
       /**
        * 对于处理指令节点,打印处理指令目标和数据
        */
       public void visit(ProcessingInstruction node) {
           System.out.println("PI : " + node.getTarget() + " "
                  + node.getText());
       }
 
       /**
        * 对于元素节点,判断是否只包含文本内容,如是,则打印标记的名字和 元素的内容。如果不是,则只打印标记的名字
        */
       public void visit(Element node) {
           if (node.isTextOnly())
              System.out.println("element : " + node.getName() + " = "
                     + node.getText());
           else
              System.out.println("--------" + node.getName() + "--------");
       }
    }
 
    public static void main(String[] argv) {
       XmlTra dom4jParser = new XmlTra(new File("students-gen.xml"));
       // dom4jParser.traversalDocumentByIterator();
       dom4jParser.traversalDocumentByVisitor();
    }
}
 
方法traversalDocumentByIterator()提供一种基于迭代的遍历实现,每个Element通过elementIterator()attributeIterator()取代其子元素和属性的迭代器。
VisitorGOF设计模式之一。其主要原理就是两种类互相保有对方的引用,并且一种作为Visitor去访问许多VisitableDOM4J中的Visitor模式只需要自定一个类实现Visitor接口即可。
public class MyVisitor extends VisitorSupport {
    public void visit(Element element) {
       System.out.println(element.getName());
    }
 
    public void visit(Attribute attr) {
       System.out.println(attr.getName());
    }
}
 
调用:  root.accept(new MyVisitor())
    Visitor接口提供多种Visit()的重载,根据XML不同的对象,将采用不同的方式来访问。上面是给出的ElementAttribute的简单实现,一般比较常用的就是这两个。VisitorSupportDOM4J提供的默认适配器,Visitor接口的Default Adapter模式,这个模式给出了各种visit(*)的空实现,以便简化代码。
    注意,这个Visitor是自动遍历所有子节点的。如果是root.accept(MyVisitor),将遍历子节点。我第一次用的时候,认为是需要自己遍历,便在递归中调用Visitor,结果可想而知。
5.使用ElementHandler
XmlHandler.java
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 XmlHandler {
    public static void main(String[] args) {
       SAXReader saxReader = new SAXReader();
       File file = new File("students.xml");
       try {
           // 添加一个ElementHandler实例。
           saxReader.addHandler("/students/student", new StudentHandler());
           saxReader.read(file);
 
       } catch (DocumentException e) {
           System.out.println(e.getMessage());
       }
    }
 
    /**
     * 定义StudentHandler处理器类,对<student>元素进行处理。
     */
    private static class StudentHandler implements ElementHandler {
       public void .Start(ElementPath path) {
           Element elt = path.getCurrent();
           System.out.println("Found student: " + elt.attribut.ue("sn"));
           // 添加对子元素<name>的处理器。
           path.addHandler("name", new NameHandler());
       }
 
       public void .End(ElementPath path) {
           // 移除对子元素<name>的处理器。
           path.removeHandler("name");
       }
    }
 
    /**
     * 定义NameHandler处理器类,对<student>的<name>子元素进行处理。
     */
    private static class NameHandler implements ElementHandler {
       public void .Start(ElementPath path) {
           System.out.println("path : " + path.getPath());
       }
 
       public void .End(ElementPath path) {
           Element elt = path.getCurrent();
           // 输出<name>元素的名字和它的文本内容。
           System.out.println(elt.getName() + " : " + elt.getText());
       }
    }
}
 
6.使用XSLT转换XML
这里必须使用JAXP的支持
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
 
import org.dom4j.Document;
import org.dom4j.io.DocumentResult;
import org.dom4j.io.DocumentSource;
 
    ……
    public Document styleDocument(Document document, String stylesheet)
           throws Exception {
 
       // load the transformer using JAXP
       TransformerFactory factory = TransformerFactory.newInstance();
       Transformer transformer = factory.newTransformer(new StreamSource(stylesheet));
 
       // now lets style the given document
       DocumentSource source = new DocumentSource(document);
       DocumentResult result = new DocumentResult();
       transformer.transform(source, result);
 
       // return the transformed document
       Document transformedDoc = result.getDocument();
       return transformedDoc;
    }
……
 
分享到:
评论

相关推荐

    dom4j解析xml文件代码示例

    dom4j解析xml文件代码示例 dom4j解析xml文件代码示例 dom4j解析xml文件代码示例

    DOM4J小示例

    dom4j的小示例,希望对大家有所帮助。dom4j是一款创建和解析xml的优秀的java XML API,是一个简单的、灵活的开放源代码的库。

    dom4j_API_示例

    dom4j是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件,可以在SourceForge上找到它。在IBM developerWorks上面可以找到一篇文章,对主流的Java XML...

    使用dom4j解析XML

    dom4j是一种解析XML文档的开放源代码XML框架。本文介绍如何使用包含在dom4j中的解析器创建并修改XML文档。dom4j API包含一个解析XML文档的工具。本文中将使用这个解析器创建一个示例XML文档,然后使用同一个解析器...

    dom4j处理xml文档说明

    dom4j处理xml文档,详细说明,内容全面,详细代码示例

    dom4j参考资料

    dom4j参考资料及示例代码

    在java中使用dom4j解析xml(示例代码)

    鉴于目前的趋势,我们这里来讲讲Dom4j的基本用法,不涉及递归等复杂操作。Dom4j的用法很多,官网上的示例有那么点儿晦涩,这里就不写了

    java使用dom4j操作xml示例代码

    dom4j是一个Java的XML API,类似于jdom,用来读写XML文件,下面我来个小例子学习他的使用方法

    专门为java程序员准备的API系列之四:dom4j英文API+中文使用示例

    看过本系列的都知道,本人上传的都是大家想找又不好找的资料,本资料为是用来解析XML文件的,中文示例有大量具体代码!

    通过dom4j解析xml字符串(示例代码)

    本篇文章主要是对通过dom4j解析xml字符串的示例代码进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助

    Java解除文件占用即Dom4j操作后实现xml关流

    主要介绍了Java解除文件占用即Dom4j操作后实现xml关流,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    java中使用dom4j解析XML文件的方法教程

    在最近的开发中用到了dom4j来解析xml文件,所以便有了这篇文章,本文主要给大家介绍了关于java中使用dom4j解析XML文件的方法教程,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

    xml解析示例代码

    xml解析

    Extjs Tree + JSON + Struts2 示例源代码

    dom4j-1.6.1.jar ezmorph-1.0.4.jar freemarker-2.3.8.jar javassist-3.8.1.jar json-lib-2.2.1-jdk15.jar log4j-1.2.13.jar ognl-2.6.11.jar struts2-core-2.0.11.jar xml-apis-1.0.b2.jar xwork-2.0.4.jar

    DOM XPATH获取img src值的query

    您可能感兴趣的文章:c#通过xpath读取xml示例java使用xpath解析xml示例分享java使用xpath和dom4j解析xml深入XPath的详解以及Java示例代码分析解析XPath语法之在C#中使用XPath的示例详解使用HtmlAgilityPack XPath ...

    java解析xml的四种方式

    java解析xml的四种方式(包括dom4j解析和jdom解析,以及示例代码)

    TwitterEggRemoval-源码

    由于此代码示例使用 DOM 中的数据,因此您需要登录您的 Twitter 帐户,转到您的关注者页面,然后向下滚动您的关注者,以便将他们加载到 DOM 中并且代码可以执行操作。 使用此操作可捕捉到屏幕底部。 cmd + ↓ 。 ...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part4

    3.5.2 dom4j api介绍 88 3.5.3 第一个实例 92 3.5.4 第二个实例 94 3.6 解析名称空间 96 3.6.1 dom和名称空间 96 3.6.2 sax和名称空间 97 3.6.3 jdom和名称空间 98 3.6.4 dom4j和名称空间 98 3.7 小结 99 ...

    Android中对xml文件解析的3种方式总结

    主要给大家介绍了关于Android中对xml文件解析的3种方式,分别是 Dom 、 SAX 和 dom4j,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part2

    3.5.2 dom4j api介绍 88 3.5.3 第一个实例 92 3.5.4 第二个实例 94 3.6 解析名称空间 96 3.6.1 dom和名称空间 96 3.6.2 sax和名称空间 97 3.6.3 jdom和名称空间 98 3.6.4 dom4j和名称空间 98 3.7 小结 99 ...

Global site tag (gtag.js) - Google Analytics