天天看点

DOM4J介绍与代码示例

原文摘自:http://zhangjunhd.blog.51cto.com/113473/126310

dom4j是dom4j.org出品的一个开源xml解析包。dom4j是一个易用的、开源的库,用于xml,xpath和xslt。它应用于java平台,采用了java集合框架并完全支持dom,sax和jaxp。

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

1.dom4j主要接口

dom4j主要接口都在org.dom4j这个包里定义。

-node为所有的dom4j中xml节点定义了多态行为;

-branch为能够包含子节点的节点如xml元素(element)和文档(docuemnts)定义了一个公共的行为;

|-element 定义xml 元素;

|-document定义了xml文档;

-documenttype 定义xml doctype声明;

-entity定义 xml entity;

-attribute定义了xml的属性;

-processinginstruction 定义 xml 处理指令;

-characterdata是一个标识借口,标识基于字符的节点。如cdata,comment, text;

|- cdata 定义了xml cdata 区域;

|-text 定义xml 文本节点;

|- comment 定义了xml注释的行为;

2.创建xml文档

示例xml:students.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>

</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");

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();

public void savedocument(document document, file outputxml) {

// 美化格式

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=dom4j.generatedocumentbymethod();

document = dom4j.generatedocumentbystring();

dom4j.savedocument(document, new file("output.xml"));

方法generatedocumentbymethod()通过调用方法构建xml文档:

1.使用documenthelper得到document实例

2.创建processing instruction

3.创建元素element

4.为元素添加注释comment

5.为元素添加属性

6.为元素添加文本值text

方法generatedocumentbystring()通过字符串转换直接构建xml文档,使用documenthelper.parsetext()来实现.

方法savedocument(document document, file outputxml)将文档输出到文件保存,可指定字符编码,可指定格式化输出。

3.修改xml文档

这里使用xpath来定位待修改的元素和属性,需要jaxen的支持。

示例中将students-gen.xml的第一个student元素的sn属性改为001,其子元素name内容改为jeff。

xmlmod.java

import java.util.iterator;

import java.util.list;

import org.dom4j.attribute;

import org.dom4j.io.saxreader;

public class xmlmod {

public void modifydocument(file inputxml) {

saxreader saxreader = new saxreader();

document document = saxreader.read(inputxml);

list list = document.selectnodes("//students/student/@sn");

iterator iter = list.iterator();

while (iter.hasnext()) {

attribute attribute = (attribute) iter.next();

if (attribute.getvalue().equals("01"))

attribute.setvalue("001");

list = document.selectnodes("//students/student");

iter = list.iterator();

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")));

catch (documentexception e) {

xmlmod dom4jparser = new xmlmod();

dom4jparser.modifydocument(new file("students-gen.xml"));

1.使用file定位文件资源,并基于此获得document实例

2.document实例的selectnodes方法可以传入xpath,并返回一个list实例,基于此使用迭代器,完成特定的应用

4.遍历xml文档

这里提供两种遍历方法,一种是基于迭代的遍历,一种是基于visitor模式的遍历。

xmltra.java

import org.dom4j.processinginstruction;

import org.dom4j.visitorsupport;

public class xmltra {

private file inputxml;

public xmltra(file inputxml) {

this.inputxml = inputxml;

public document getdocument() {

document = saxreader.read(inputxml);

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() + " = "

else

system.out.println("--------" + node.getname() + "--------");

xmltra dom4jparser = new xmltra(new file("students-gen.xml"));

// dom4jparser.traversaldocumentbyiterator();

dom4jparser.traversaldocumentbyvisitor();

方法traversaldocumentbyiterator()提供一种基于迭代的遍历实现,每个element通过elementiterator()和attributeiterator()取代其子元素和属性的迭代器。

visitor是gof设计模式之一。其主要原理就是两种类互相保有对方的引用,并且一种作为visitor去访问许多visitable。dom4j中的visitor模式只需要自定一个类实现visitor接口即可。

public class myvisitor extends visitorsupport {

public void visit(element element) {

public void visit(attribute attr) {

system.out.println(attr.getname());

调用: root.accept(new myvisitor())

visitor接口提供多种visit()的重载,根据xml不同的对象,将采用不同的方式来访问。上面是给出的element和attribute的简单实现,一般比较常用的就是这两个。visitorsupport是dom4j提供的默认适配器,visitor接口的default adapter模式,这个模式给出了各种visit(*)的空实现,以便简化代码。

注意,这个visitor是自动遍历所有子节点的。如果是root.accept(myvisitor),将遍历子节点。我第一次用的时候,认为是需要自己遍历,便在递归中调用visitor,结果可想而知。

5.使用elementhandler

xmlhandler.java

import org.dom4j.elementhandler;

import org.dom4j.elementpath;

public class xmlhandler {

public static void main(string[] args) {

file file = new file("students.xml");

// 添加一个elementhandler实例。

saxreader.addhandler("/students/student", newstudenthandler());

saxreader.read(file);

* 定义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 {

system.out.println("path : " + path.getpath());

// 输出<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.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(newstreamsource(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;