原文摘自: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;