DOM4J的使用(DOM4J对XML的解析即增删改查)
2014-01-02 22:50
561 查看
dom4j是一个Java的XML API,类似于jdom,用来读写XML文件的。dom4j是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件,可以在SourceForge上找到它。在IBM developerWorks上面可以找到一篇文章,对主流的Java XML API进行的性能、功能和易用性的评测,dom4j无论在那个方面都是非常出色的。如今你可以看到越来越多的Java软件都在使用dom4j来读写XML,特别值得一提的是连Sun的JAXM也在用dom4j。这是必须使用的jar包,
Hibernate用它来读写配置文件。
在国内比较流行的是使用JDOM作为解析器,两者各擅其长,但DOM4J最大的特色是使用大量的接口,这也是它被认为比JDOM灵活的主要原因。大师不是说过么,“面向接口编程”。目前使用DOM4J的已经越来越多。如果你善于使用JDOM,不妨继续用下去,只看看本篇文章作为了解与比较,如果你正要采用一种解析器,不如就用DOM4J吧。
要想弄懂这套接口,关键的是要明白接口的继承关系:
interface java.lang.Cloneable
interface org.dom4j.Node
interface org.dom4j.Attribute
interface org.dom4j.Branch
interface org.dom4j.Document
interface org.dom4j.Element
interface org.dom4j.CharacterData
interface org.dom4j.CDATA
interface org.dom4j.Comment
interface org.dom4j.Text
interface org.dom4j.DocumentType
interface org.dom4j.Entity
interface org.dom4j.ProcessingInstruction
一目了然,很多事情都清楚了。大部分都是由Node继承来的。知道这些关系,将来写程序就不会出现ClassCastException了。
下面给出一些例子(部分摘自DOM4J自带的文档),简单说一下如何使用。
一、 读取并解析XML文档:
[align=left]其中,reader的read方法是重载的,可以从InputStream, File, Url等多种不同的源来读取。得到的Document对象就带表了整个XML。[/align]
[align=left]读取的字符编码是按照XML文件头定义的编码来转换。如果遇到乱码问题,注意要把各处的编码名称保持一致即可。[/align]
[align=left]二、取得Root节点[/align]
[align=left]读取后的第二步,就是得到Root节点。熟悉XML的人都知道,一切XML分析都是从Root元素开始的。[/align]
三、 遍历XML树(三种方法)
1)枚举:
2)递归
3)Visitor模式
[align=left] Visitor接口提供多种Visit()的重载,根据XML不同的对象,将采用不同的方式来访问。上面是给出的Element和Attribute的简单实现,一般比较常用的就是这两个。VisitorSupport是DOM4J提供的默认适配器,Visitor接口的Default Adapter模式,这个模式给出了各种visit(*)的空实现,以便简化代码。[/align]
注意,这个Visitor是自动遍历所有子节点的。如果是root.accept(MyVisitor),将遍历子节点。
五、 字符串与XML的转换
[align=left]有时候经常要用到字符串转换为XML或反之,[/align]
[align=left]六、 用XSLT转换XML[/align]
[align=left]七、 创建XML[/align]
[align=left] 一般创建XML是写文件前的工作,这就像StringBuffer一样容易。[/align]
[align=left]八、文件输出[/align]
[align=left] 一个简单的输出方法是将一个Document或任何的Node通过write方法输出[/align]
[align=left] 如果你想改变输出的格式,比如美化输出或缩减格式,可以用XMLWriter类[/align]
最后附上,我做测试一份简单代码:
package com.test;
import java.io.File;
import java.io.FileWriter;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class XMLTest {
/**
* 建立一个XML文档,文档名由输入属性决定
* @param filename 需建立的文件名
* @return 返回操作结果, 0表失败, 1表成功
*/
public int createXMLFile(String filename){
/** 返回操作结果, 0表失败, 1表成功 */
int returnValue = 0;
/** 建立document对象 */
Document document = DocumentHelper.createDocument();
/** 建立XML文档的根books */
Element booksElement = document.addElement("books");
/** 加入一行注释 */
booksElement.addComment("This is a test for dom4j, holen, 2004.9.11");
/** 加入第一个book节点 */
Element bookElement = booksElement.addElement("book");
/** 加入show属性内容 */
bookElement.addAttribute("show","yes");
/** 加入title节点 */
Element titleElement = bookElement.addElement("title");
/** 为title设置内容 */
titleElement.setText("Dom4j Tutorials");
/** 类似的完成后两个book */
bookElement = booksElement.addElement("book");
bookElement.addAttribute("show","yes");
titleElement = bookElement.addElement("title");
titleElement.setText("Lucene Studing");
bookElement = booksElement.addElement("book");
bookElement.addAttribute("show","no");
titleElement = bookElement.addElement("title");
titleElement.setText("Lucene in Action");
/** 加入owner节点 */
Element ownerElement = booksElement.addElement("owner");
ownerElement.setText("O'Reilly");
/** 格式化输出,类型IE浏览一样 */
OutputFormat format = OutputFormat.createPrettyPrint();
/** 指定XML编码 */
format.setEncoding("GBK");
try{
/** 将document中的内容写入文件中 */
XMLWriter writer = new XMLWriter(new FileWriter(new File(filename)),format);
writer.write(document);
writer.close();
/** 执行成功,需返回1 */
returnValue = 1;
}catch(Exception ex){
ex.printStackTrace();
}
return returnValue;
}
/**
* 修改XML文件中内容,并另存为一个新文件
* 重点掌握dom4j中如何添加节点,修改节点,删除节点
* @param filename 修改对象文件
* @param newfilename 修改后另存为该文件
* @return 返回操作结果, 0表失败, 1表成功
*/
public int ModiXMLFile(String filename,String newfilename){
int returnValue = 0;
try{
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new File(filename));
/** 修改内容之一: 如果book节点中show属性的内容为yes,则修改成no */
/** 先用xpath查找对象 */
List list = document.selectNodes("/books/book/@show" );
Iterator iter = list.iterator();
while(iter.hasNext()){
Attribute attribute = (Attribute)iter.next();
if(attribute.getValue().equals("yes")){
attribute.setValue("no");
}
}
/**
* 修改内容之二: 把owner项内容改为Tshinghua
* 并在owner节点中加入date节点,date节点的内容为2004-09-11,还为date节点添加一个属性type
*/
list = document.selectNodes("/books/owner" );
iter = list.iterator();
if(iter.hasNext()){
Element ownerElement = (Element)iter.next();
ownerElement.setText("Tshinghua");
Element dateElement = ownerElement.addElement("date");
dateElement.setText("2004-09-11");
dateElement.addAttribute("type","Gregorian calendar");
}
/** 修改内容之三: 若title内容为Dom4j Tutorials,则删除该节点 */
list = document.selectNodes("/books/book");
iter = list.iterator();
while(iter.hasNext()){
Element bookElement = (Element)iter.next();
Iterator iterator = bookElement.elementIterator("title");
while(iterator.hasNext()){
Element titleElement=(Element)iterator.next();
if(titleElement.getText().equals("Dom4j Tutorials")){
bookElement.remove(titleElement);
}
}
}
try{
/** 将document中的内容写入文件中 */
XMLWriter writer = new XMLWriter(new FileWriter(new File(newfilename)));
writer.write(document);
writer.close();
/** 执行成功,需返回1 */
returnValue = 1;
}catch(Exception ex){
ex.printStackTrace();
}
}catch(Exception ex){
ex.printStackTrace();
}
return returnValue;
}
/**
* 格式化XML文档,并解决中文问题
* @param filename
* @return
*/
public int formatXMLFile(String filename){
int returnValue = 0;
try{
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new File(filename));
XMLWriter writer = null;
/** 格式化输出,类型IE浏览一样 */
OutputFormat format = OutputFormat.createPrettyPrint();
/** 指定XML编码 */
format.setEncoding("UTF-8");
writer= new XMLWriter(new FileWriter(new File(filename)),format);
writer.write(document);
writer.close();
/** 执行成功,需返回1 */
returnValue = 1;
}catch(Exception ex){
ex.printStackTrace();
}
return returnValue;
}
public static void main(String[] args) {
XMLTest xmlTest= new XMLTest();
System.out.println(xmlTest.createXMLFile("holen.xml"));
// System.out.println(xmlTest.ModiXMLFile("holen.xml", "newholen.xml"));
// System.out.println(xmlTest.formatXMLFile("holen.xml"));
}
}
Hibernate用它来读写配置文件。
在国内比较流行的是使用JDOM作为解析器,两者各擅其长,但DOM4J最大的特色是使用大量的接口,这也是它被认为比JDOM灵活的主要原因。大师不是说过么,“面向接口编程”。目前使用DOM4J的已经越来越多。如果你善于使用JDOM,不妨继续用下去,只看看本篇文章作为了解与比较,如果你正要采用一种解析器,不如就用DOM4J吧。
[align=left]Attribute[/align] | [align=left]Attribute定义了XML的属性[/align] |
[align=left]Branch[/align] | [align=left]Branch为能够包含子节点的节点如XML元素(Element)和文档(Docuemnts)定义了一个公共的行为,[/align] |
[align=left]CDATA[/align] | [align=left]CDATA 定义了XML CDATA 区域[/align] |
[align=left]CharacterData[/align] | [align=left]CharacterData是一个标识借口,标识基于字符的节点。如CDATA,Comment, Text.[/align] |
[align=left]Comment[/align] | [align=left]Comment 定义了XML注释的行为[/align] |
[align=left]Document[/align] | [align=left]定义了XML文档[/align] |
[align=left]DocumentType[/align] | [align=left]DocumentType 定义XML DOCTYPE声明[/align] |
[align=left]Element[/align] | [align=left]Element定义XML 元素[/align] |
[align=left]ElementHandler[/align] | [align=left]ElementHandler定义了 Element 对象的处理器[/align] |
[align=left]ElementPath[/align] | [align=left]被 ElementHandler 使用,用于取得当前正在处理的路径层次信息[/align] |
[align=left]Entity[/align] | [align=left]Entity定义 XML entity[/align] |
[align=left]Node[/align] | [align=left]Node为所有的dom4j中XML节点定义了多态行为[/align] |
[align=left]NodeFilter[/align] | [align=left]NodeFilter 定义了在dom4j节点中产生的一个滤镜或谓词的行为(predicate)[/align] |
[align=left]ProcessingInstruction[/align] | [align=left]ProcessingInstruction 定义 XML 处理指令.[/align] |
[align=left]Text[/align] | [align=left]Text 定义XML 文本节点.[/align] |
[align=left]Visitor[/align] | [align=left]Visitor 用于实现Visitor模式.[/align] |
[align=left]XPath[/align] | [align=left]XPath 在分析一个字符串后会提供一个XPath 表达式[/align] |
interface java.lang.Cloneable
interface org.dom4j.Node
interface org.dom4j.Attribute
interface org.dom4j.Branch
interface org.dom4j.Document
interface org.dom4j.Element
interface org.dom4j.CharacterData
interface org.dom4j.CDATA
interface org.dom4j.Comment
interface org.dom4j.Text
interface org.dom4j.DocumentType
interface org.dom4j.Entity
interface org.dom4j.ProcessingInstruction
一目了然,很多事情都清楚了。大部分都是由Node继承来的。知道这些关系,将来写程序就不会出现ClassCastException了。
下面给出一些例子(部分摘自DOM4J自带的文档),简单说一下如何使用。
一、 读取并解析XML文档:
[align=left] // 从文件读取XML,输入文件名,返回XML文档[/align] [align=left] public Document read(String fileName) throws MalformedURLException, DocumentException {[/align] [align=left] SAXReader reader = new SAXReader();[/align] [align=left] Document document = reader.read(new File(fileName));[/align] [align=left] return document;[/align] [align=left] }[/align] |
[align=left]读取的字符编码是按照XML文件头定义的编码来转换。如果遇到乱码问题,注意要把各处的编码名称保持一致即可。[/align]
[align=left]二、取得Root节点[/align]
[align=left]读取后的第二步,就是得到Root节点。熟悉XML的人都知道,一切XML分析都是从Root元素开始的。[/align]
[align=left] public Element getRootElement(Document doc){[/align] [align=left] return doc.getRootElement();[/align] [align=left] }[/align] |
1)枚举:
[align=left] // 枚举所有子节点[/align] [align=left] for ( Iterator i = root.elementIterator(); i.hasNext(); ) {[/align] [align=left] Element element = (Element) i.next();[/align] [align=left] // do something[/align] [align=left] }[/align] [align=left] // 枚举名称为foo的节点[/align] [align=left] for ( Iterator i = root.elementIterator(foo); i.hasNext();) {[/align] [align=left] Element foo = (Element) i.next();[/align] [align=left] // do something[/align] [align=left] }[/align] [align=left] // 枚举属性[/align] [align=left] for ( Iterator i = root.attributeIterator(); i.hasNext(); ) {[/align] [align=left] Attribute attribute = (Attribute) i.next();[/align] [align=left] // do something[/align] [align=left] }[/align] |
[align=left] public void treeWalk() {[/align] [align=left] treeWalk(getRootElement());[/align] [align=left] }[/align] [align=left] public void treeWalk(Element element) {[/align] [align=left] for (int i = 0, size = element.nodeCount(); i < size; i++) {[/align] [align=left] Node node = element.node(i);[/align] [align=left] if (node instanceof Element) {[/align] [align=left] treeWalk((Element) node);[/align] [align=left] } else { // do something....[/align] [align=left] }[/align] [align=left] }[/align] [align=left]}[/align] |
[align=left] public class MyVisitor extends VisitorSupport {[/align] [align=left] public void visit(Element element){[/align] [align=left] System.out.println(element.getName());[/align] [align=left] }[/align] [align=left] public void visit(Attribute attr){[/align] [align=left] System.out.println(attr.getName());[/align] [align=left] }[/align] [align=left] }[/align] [align=left] 调用: root.accept(new MyVisitor())[/align] |
注意,这个Visitor是自动遍历所有子节点的。如果是root.accept(MyVisitor),将遍历子节点。
五、 字符串与XML的转换
[align=left]有时候经常要用到字符串转换为XML或反之,[/align]
[align=left] // XML转字符串[/align] [align=left] Document document = ...;[/align] [align=left] String text = document.asXML();[/align] [align=left]// 字符串转XML[/align] [align=left] String text = James ;[/align] [align=left] Document document = DocumentHelper.parseText(text);[/align] |
[align=left] public Document styleDocument([/align] [align=left] Document document,[/align] [align=left] String stylesheet[/align] [align=left] ) throws Exception {[/align] [align=left] // load the transformer using JAXP[/align] [align=left] TransformerFactory factory = TransformerFactory.newInstance();[/align] [align=left] Transformer transformer = factory.newTransformer([/align] [align=left] new StreamSource( stylesheet )[/align] [align=left] );[/align] [align=left] // now lets style the given document[/align] [align=left] DocumentSource source = new DocumentSource( document );[/align] [align=left] DocumentResult result = new DocumentResult();[/align] [align=left] transformer.transform( source, result );[/align] [align=left] // return the transformed document[/align] [align=left] Document transformedDoc = result.getDocument();[/align] [align=left] return transformedDoc;[/align] [align=left]}[/align] |
[align=left] 一般创建XML是写文件前的工作,这就像StringBuffer一样容易。[/align]
[align=left] public Document createDocument() {[/align] [align=left] Document document = DocumentHelper.createDocument();[/align] [align=left] Element root = document.addElement(root);[/align] [align=left] Element author1 =[/align] [align=left] root[/align] [align=left] .addElement(author)[/align] [align=left] .addAttribute(name, James)[/align] [align=left] .addAttribute(location, UK)[/align] [align=left] .addText(James Strachan);[/align] [align=left] Element author2 =[/align] [align=left] root[/align] [align=left] .addElement(author)[/align] [align=left] .addAttribute(name, Bob)[/align] [align=left] .addAttribute(location, US)[/align] [align=left] .addText(Bob McWhirter);[/align] [align=left] return document;[/align] [align=left] }[/align] |
[align=left] 一个简单的输出方法是将一个Document或任何的Node通过write方法输出[/align]
[align=left] FileWriter out = new FileWriter( foo.xml );[/align] [align=left] document.write(out);[/align] |
[align=left] public void write(Document document) throws IOException {[/align] [align=left] // 指定文件[/align] [align=left] XMLWriter writer = new XMLWriter([/align] [align=left] new FileWriter( output.xml )[/align] [align=left] );[/align] [align=left] writer.write( document );[/align] [align=left] writer.close();[/align] [align=left] // 美化格式[/align] [align=left] OutputFormat format = OutputFormat.createPrettyPrint();[/align] [align=left] writer = new XMLWriter( System.out, format );[/align] [align=left] writer.write( document );[/align] [align=left] // 缩减格式[/align] [align=left] format = OutputFormat.createCompactFormat();[/align] [align=left] writer = new XMLWriter( System.out, format );[/align] [align=left] writer.write( document );[/align] [align=left] }[/align] |
package com.test;
import java.io.File;
import java.io.FileWriter;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class XMLTest {
/**
* 建立一个XML文档,文档名由输入属性决定
* @param filename 需建立的文件名
* @return 返回操作结果, 0表失败, 1表成功
*/
public int createXMLFile(String filename){
/** 返回操作结果, 0表失败, 1表成功 */
int returnValue = 0;
/** 建立document对象 */
Document document = DocumentHelper.createDocument();
/** 建立XML文档的根books */
Element booksElement = document.addElement("books");
/** 加入一行注释 */
booksElement.addComment("This is a test for dom4j, holen, 2004.9.11");
/** 加入第一个book节点 */
Element bookElement = booksElement.addElement("book");
/** 加入show属性内容 */
bookElement.addAttribute("show","yes");
/** 加入title节点 */
Element titleElement = bookElement.addElement("title");
/** 为title设置内容 */
titleElement.setText("Dom4j Tutorials");
/** 类似的完成后两个book */
bookElement = booksElement.addElement("book");
bookElement.addAttribute("show","yes");
titleElement = bookElement.addElement("title");
titleElement.setText("Lucene Studing");
bookElement = booksElement.addElement("book");
bookElement.addAttribute("show","no");
titleElement = bookElement.addElement("title");
titleElement.setText("Lucene in Action");
/** 加入owner节点 */
Element ownerElement = booksElement.addElement("owner");
ownerElement.setText("O'Reilly");
/** 格式化输出,类型IE浏览一样 */
OutputFormat format = OutputFormat.createPrettyPrint();
/** 指定XML编码 */
format.setEncoding("GBK");
try{
/** 将document中的内容写入文件中 */
XMLWriter writer = new XMLWriter(new FileWriter(new File(filename)),format);
writer.write(document);
writer.close();
/** 执行成功,需返回1 */
returnValue = 1;
}catch(Exception ex){
ex.printStackTrace();
}
return returnValue;
}
/**
* 修改XML文件中内容,并另存为一个新文件
* 重点掌握dom4j中如何添加节点,修改节点,删除节点
* @param filename 修改对象文件
* @param newfilename 修改后另存为该文件
* @return 返回操作结果, 0表失败, 1表成功
*/
public int ModiXMLFile(String filename,String newfilename){
int returnValue = 0;
try{
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new File(filename));
/** 修改内容之一: 如果book节点中show属性的内容为yes,则修改成no */
/** 先用xpath查找对象 */
List list = document.selectNodes("/books/book/@show" );
Iterator iter = list.iterator();
while(iter.hasNext()){
Attribute attribute = (Attribute)iter.next();
if(attribute.getValue().equals("yes")){
attribute.setValue("no");
}
}
/**
* 修改内容之二: 把owner项内容改为Tshinghua
* 并在owner节点中加入date节点,date节点的内容为2004-09-11,还为date节点添加一个属性type
*/
list = document.selectNodes("/books/owner" );
iter = list.iterator();
if(iter.hasNext()){
Element ownerElement = (Element)iter.next();
ownerElement.setText("Tshinghua");
Element dateElement = ownerElement.addElement("date");
dateElement.setText("2004-09-11");
dateElement.addAttribute("type","Gregorian calendar");
}
/** 修改内容之三: 若title内容为Dom4j Tutorials,则删除该节点 */
list = document.selectNodes("/books/book");
iter = list.iterator();
while(iter.hasNext()){
Element bookElement = (Element)iter.next();
Iterator iterator = bookElement.elementIterator("title");
while(iterator.hasNext()){
Element titleElement=(Element)iterator.next();
if(titleElement.getText().equals("Dom4j Tutorials")){
bookElement.remove(titleElement);
}
}
}
try{
/** 将document中的内容写入文件中 */
XMLWriter writer = new XMLWriter(new FileWriter(new File(newfilename)));
writer.write(document);
writer.close();
/** 执行成功,需返回1 */
returnValue = 1;
}catch(Exception ex){
ex.printStackTrace();
}
}catch(Exception ex){
ex.printStackTrace();
}
return returnValue;
}
/**
* 格式化XML文档,并解决中文问题
* @param filename
* @return
*/
public int formatXMLFile(String filename){
int returnValue = 0;
try{
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new File(filename));
XMLWriter writer = null;
/** 格式化输出,类型IE浏览一样 */
OutputFormat format = OutputFormat.createPrettyPrint();
/** 指定XML编码 */
format.setEncoding("UTF-8");
writer= new XMLWriter(new FileWriter(new File(filename)),format);
writer.write(document);
writer.close();
/** 执行成功,需返回1 */
returnValue = 1;
}catch(Exception ex){
ex.printStackTrace();
}
return returnValue;
}
public static void main(String[] args) {
XMLTest xmlTest= new XMLTest();
System.out.println(xmlTest.createXMLFile("holen.xml"));
// System.out.println(xmlTest.ModiXMLFile("holen.xml", "newholen.xml"));
// System.out.println(xmlTest.formatXMLFile("holen.xml"));
}
}
相关文章推荐
- 使用dom4j解析xml与增删改查
- 解析xml和生成xml(使用dom4j和velocity)
- 【XML解析】(4)Java下使用DOM4J解析方式对XML文档进行解析
- 使用Dom4j解析XML
- 【XML解析】(5)DOM4J中的XPath的使用方式及其【完整语法详细说明】
- 使用Dom4j解析XML
- Java XML解析工具 dom4j介绍及使用实例
- 使用 dom4j 解析 XML
- 使用 dom4j 解析 XML
- 使用Dom4j 解析XML
- dom4j解析XML之【增删改查】
- 单例设计模式中使用dom4j来完成(数据库配置文件)xml的解析,并完成数据库的连接
- 在java中使用dom4j解析xml
- 使用Dom4j解析XML
- XML_DTD约束和XML_Schema约束以及使用dom4j解析
- 使用 dom4j 解析 XML
- 使用 dom4j 解析XML
- xml简单介绍及使用dom4j进行解析
- 在java中使用dom4j解析xml(示例代码)
- 使用Dom4j解析XML