博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
DOM4J介绍与代码示例
阅读量:6805 次
发布时间:2019-06-26

本文共 11536 字,大约阅读时间需要 38 分钟。

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
>
    
</
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();
           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();
           
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()
取代其子元素和属性的迭代器。
Visitor
GOF
设计模式之一。其主要原理就是两种类互相保有对方的引用,并且一种作为
Visitor
去访问许多
Visitable
DOM4J
中的
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
不同的对象,将采用不同的方式来访问。上面是给出的
Element
Attribute
的简单实现,一般比较常用的就是这两个。
VisitorSupport
DOM4J
提供的默认适配器,
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;
    }
……
 
本文转自zhangjunhd51CTO博客,原文链接:http://blog.51cto.com/zhangjunhd/126310,如需转载请自行联系原作者
你可能感兴趣的文章
Codeforces 894 A B 组合数学 比赛
查看>>
C#后台调用前台javascript的五种方法小结
查看>>
GDB 多线程调试基本命令
查看>>
C++中的友元
查看>>
MySql常用函数
查看>>
移动端 触屏滑动条菜单(完善版 转)
查看>>
可变参数函数的实现
查看>>
ABP官方文档翻译 4.4 授权
查看>>
小程序-提交信息(姓名,电话)
查看>>
Object.defineProperties——MEAN开发后台的Model层
查看>>
Python 学习笔记11 函数模块
查看>>
从C#垃圾回收(GC)机制中挖掘性能优化方案
查看>>
qt cef嵌入web(二)
查看>>
qt捕获全局windows消息
查看>>
Qt之自定义QLineEdit右键菜单
查看>>
项目Alpha冲刺(团队6/10)
查看>>
springboot2.0+dubbo整合分布式服务发布和调用
查看>>
Debian系统常用配置
查看>>
风景最美的地方
查看>>
android系列7.单元测试学习
查看>>