DOM4J 是 dom4j.org 出品的一個(gè)開源 XML 解析包,它的網(wǎng)站中這樣定義:
Dom4j is an easy to use, open source library for working with XML, XPath and XSLT on the Java platform using the Java Collections Framework and with full support for DOM, SAX and JAXP.
Dom4j 是一個(gè)易用的、開源的庫,用于 XML , XPath 和 XSLT 。它應(yīng)用于 Java 平臺(tái),采用了 Java 集合框架并完全支持 DOM , SAX 和 JAXP 。
Dom4j.jar
包括 dom4j 類和 XPath 引擎,但是不含 SAX 與 DOM 接口。最好使用 1.5 的版本 , 有兩個(gè)包文件 , dom4j-1.5.jar 和 dom4j-full.jar ,目前 1.6 的還不穩(wěn)定。下載網(wǎng)址: http://sourceforge.net/projects/dom4j 。
它的主要接口都在 org.dom4j 這個(gè)包里定義:
|
Attribute 定義了 XML 的屬性
|
|
Branch 為能夠包含子節(jié)點(diǎn)的節(jié)點(diǎn)如 XML 元素 (Element) 和文檔 (Docuemnts) 定義了一個(gè)公共的行為,
|
|
CDATA 定義了 XML CDATA 區(qū)域
|
|
CharacterData 是一個(gè)標(biāo)識(shí)借口,標(biāo)識(shí)基于字符的節(jié)點(diǎn)。如 CDATA , Comment, Text.
|
|
Comment 定義了 XML 注釋的行為
|
|
定義了 XML 文檔
|
|
DocumentType 定義 XML DOCTYPE 聲明
|
|
Element 定義 XML 元素
|
|
ElementHandler 定義了 Element 對(duì)象的處理器
|
|
被 ElementHandler 使用,用于取得當(dāng)前正在處理的路徑層次信息
|
|
Entity 定義 XML entity
|
|
Node 為所有的 dom4j 中 XML 節(jié)點(diǎn) 定義了多態(tài)行為
|
|
NodeFilter 定義了在 dom4j 節(jié)點(diǎn)中產(chǎn)生的一個(gè)濾鏡或謂詞的行為( predicate )
|
|
ProcessingInstruction 定義 XML 處理指令 .
|
|
Text 定義 XML 文本節(jié)點(diǎn) .
|
|
Visitor 用于實(shí)現(xiàn) Visitor 模式 .
|
|
XPath 在分析一個(gè)字符串后會(huì)提供一個(gè) XPath 表達(dá)式
|
1. 讀取并解析XML文檔:
讀寫XML文檔主要依賴于org.dom4j.io包,其中提供DOMReader和SAXReader兩類不同方式,而調(diào)用方式是一樣的。這就是依靠接口的好處。















其中,reader的read方法是重載的,可以從InputStream, File, Url等多種不同的源來讀取。得到的Document對(duì)象就帶表了整個(gè)XML。
根據(jù)本人自己的經(jīng)驗(yàn),讀取的字符編碼是按照XML文件頭定義的編碼來轉(zhuǎn)換。如果遇到亂碼問題,注意要把各處的編碼名稱保持一致即可。
2. 取得Root節(jié)點(diǎn)
讀取后的第二步,就是得到Root節(jié)點(diǎn)。熟悉XML的人都知道,一切XML分析都是從Root元素開始的。
public Element getRootElement(Document doc)
{
return doc.getRootElement();
}
3. 遍歷XML樹
DOM4J提供至少3種遍歷節(jié)點(diǎn)的方法:
1) 枚舉(Iterator)
// 枚舉所有子節(jié)點(diǎn)



Element element = (Element) i.next(); // do something
}
// 枚舉名稱為foo的節(jié)點(diǎn)



Element foo = (Element) i.next();
// do something }
// 枚舉屬性



Attribute attribute = (Attribute) i.next(); // do something }

2)遞歸
遞歸也可以采用Iterator作為枚舉手段,但文檔中提供了另外的做法








for (int i = 0, size = element.nodeCount(); i < size; i++)

if (node instanceof Element)

else


} }}
4. XPath支持
DOM4J對(duì)XPath有良好的支持,如訪問一個(gè)節(jié)點(diǎn),可直接用XPath選擇。



List list = document.selectNodes( //foo/bar );
Node node = document.selectSingleNode(//foo/bar/author);
String name = node.valueOf( @name ); }
例如,如果你想查找XHTML文檔中所有的超鏈接,下面的代碼可以實(shí)現(xiàn):



List list = document.selectNodes( //a/@href );
for (Iterator iter = list.iterator(); iter.hasNext(); ) {
Attribute attribute = (Attribute) iter.next();
String url = attribute.getValue(); } }
5. 字符串與XML的轉(zhuǎn)換
有時(shí)候經(jīng)常要用到字符串轉(zhuǎn)換為XML或反之,
// XML轉(zhuǎn)字符串
Document document =;
String text = document.asXML();// 字符串轉(zhuǎn)XML
String text = <person> <name>James</name> </person>;
Document document = DocumentHelper.parseText(text);
7. 創(chuàng)建XML
一般創(chuàng)建XML是寫文件前的工作,這就像StringBuffer一樣容易。



Document document = DocumentHelper.createDocument();
Element root = document.addElement(root);
Element author1 = root .addElement(author) .addAttribute(name, James) .addAttribute(location, UK) .addText(James Strachn);
Element author2 = root .addElement(author) .addAttribute(name, Bob) .addAttribute(location, US) .addText(Bob McWhirter);
return document;
如果你想改變輸出的格式,比如美化輸出或縮減格式,可以用XMLWriter類



XMLWriter writer = new XMLWriter( new FileWriter( output.xml ) );
writer.write( document );
writer.close();
// 美化格式
OutputFormat format = OutputFormat.createPrettyPrint();
writer = new XMLWriter( System.out, format );
writer.write( document ); // 縮減格式
format = OutputFormat.createCompactFormat();
writer = new XMLWriter( System.out, format );
writer.write( document ); }
一、 使用
1、創(chuàng)建XML文檔
dom4j創(chuàng)建xmlgenerateDocument()需要以下四步:創(chuàng)建文檔、添加根元素、添加子元素、添加元素內(nèi)容、寫XML文件。
使用的類有org.dom4j.Document,org.dom4j.DocumentHelper,
org.dom4j.Element 類。
代碼如下:
import org.dom4j.Document; //導(dǎo)入dom4j API 類
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Attribute;
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.dom4j.io.SAXReader;
import java.io.*;
import java.util.List;
import java.util.Iterator;
class Rt
{
public Document generateDocument()
{
//使用DocumentHelper 類創(chuàng)建一個(gè)文檔實(shí)例。DocumentHelper 是生成XML 文檔節(jié)點(diǎn)的dom4j API 工廠類。
Document document = DocumentHelper.createDocument();
//使用addElement() 方法創(chuàng)建根元素catalog 。addElement() 用于向XML 文檔中增加元素。
Element catalogElement = document.addElement("catalog");
//在catalog 元素中使用addComment() 方法添加注釋“An XML catalog”。
catalogElement.addComment("An XML Catalog");
//在catalog 元素中使用addProcessingInstruction() 方法增加一個(gè)處理指令。
catalogElement.addProcessingInstruction("target","text");
//在catalog 元素中使用addElement() 方法增加journal 元素。
Element journalElement = catalogElement.addElement("journal");
//使用addAttribute() 方法向journal 元素添加title 和publisher 屬性
journalElement.addAttribute("title", "XML Zone");
journalElement.addAttribute("publisher", "IBM developerWorks");
//向journal 元素中添加article 元素,使用addAttribute()方法向article元素添加level,date屬性
Element articleElement=journalElement.addElement("article");
articleElement.addAttribute("level", "Intermediate");
articleElement.addAttribute("date", "December-2001");
//向article元素中添加title元素
Element titleElement=articleElement.addElement("title");
//使用setText() 方法設(shè)置article 元素的文本
titleElement.setText("Java configuration with XML Schema");
//向article元素中添加author元素
Element authorElement=articleElement.addElement("author");
//向author元素中添加firstname,lastname元素,并用setText()設(shè)置他們的文本
Element firstNameElement=authorElement.addElement("firstname");
firstNameElement.setText("Marcello");
Element lastNameElement=authorElement.addElement("lastname");
lastNameElement.setText("Vitaletti");
return document;
//使用addDocType() 方法添加文檔類型說明
//document.addDocType("catalog",null,"file://c:/Dtds/catalog.dtd");
/**try
{
XMLWriter output = new XMLWriter(
new FileWriter( new File("mycatalog.xml") ));
output.write( document );
output.close();
}
catch(IOException e)
{System.out.println(e.getMessage());}**/
}
/**
* 格式化XML文檔,并按指定字符集輸出
* @param document
* @param fileName
* @param encoding 編碼格式
* @return 返回操作結(jié)果, 0表失敗, 1表成功
*/
public static int saveXml(Document document,
String fileName,
String encoding)
throws UnsupportedEncodingException,
FileNotFoundException,
IOException{
int returnValue = 0;
XMLWriter output = null;
/** 格式化輸出,類型IE瀏覽一樣*/
OutputFormat format = OutputFormat.createPrettyPrint();
/** 指定XML字符集編碼*/
format.setEncoding(encoding);
output = new XMLWriter(new FileOutputStream(new File(fileName)), format);
output.write(document);
output.close();
/** 執(zhí)行成功,需返回1 */
returnValue = 1;
return returnValue;
}
/**
* 修改XML文檔,并按指定字符集輸出
* @param inputXml
* @param modified_filename 修改后的文件名(含絕對(duì)路徑)
* @return 返回操作結(jié)果, 0表失敗, 1表成功
*/
try{
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(inputXml);
//根據(jù)XPath語法查詢結(jié)點(diǎn)catalog下的journal下的article的level屬性
List list = document.selectNodes("/catalog/journal/article/@level" );
Iterator iter=list.iterator();
while(iter.hasNext()){
Attribute attribute=(Attribute)iter.next();
if(attribute.getValue().equals("Intermediate")) //如果屬性值是Intermediate
attribute.setValue("Introductory");
}
list = document.selectNodes("http://article/@date" );
iter=list.iterator();
while(iter.hasNext()){
Attribute attribute=(Attribute)iter.next();
if(attribute.getValue().equals("December-2001"))
attribute.setValue("October-2002");
}
list = document.selectNodes("http://article" );
iter=list.iterator();
while(iter.hasNext()){
Element element=(Element)iter.next();
Iterator iterator=element.elementIterator("title");
while(iterator.hasNext()){
Element titleElement=(Element)iterator.next();
if(titleElement.getText().equals("Java configuration with XML Schema"))
titleElement.setText("Create flexible and extensible XML schema"); }
}
list = document.selectNodes("http://article/author" );
iter=list.iterator();
while(iter.hasNext()){
Element element=(Element)iter.next();
Iterator iterator=element.elementIterator("firstname");
while(iterator.hasNext()){
Element firstNameElement=(Element)iterator.next();
if(firstNameElement.getText().equals("Marcello"))
firstNameElement.setText("Ayesha");
}
}
list = document.selectNodes("http://article/author" );
iter=list.iterator();
while(iter.hasNext()){
Element element=(Element)iter.next();
Iterator iterator=element.elementIterator("lastname");
while(iterator.hasNext()){
Element lastNameElement=(Element)iterator.next();
if(lastNameElement.getText().equals("Vitaletti"))
lastNameElement.setText("Malik");
}
}
XMLWriter output = new XMLWriter(
new FileWriter( new File(modified_filename) ));
output.write( document );
output.close();
}
catch(DocumentException e)
{
System.out.println(e.getMessage());
}
catch(IOException e){
System.out.println(e.getMessage());
}
/** 執(zhí)行成功,需返回1 */
returnValue = 1;
return returnValue;
}
public static void main(String[] argv)
{
Rt savedomtoxml=new Rt();
Document doc=savedomtoxml.generateDocument();
try{
int re=savedomtoxml.saveXml(doc,"savexml.xml","gb2312"); //生成的xml文件默認(rèn)狀態(tài)和類文件在同一個(gè)目錄下
System.out.println(re);
}
catch(IOException e)
{System.out.println(e.getMessage());}
try{
int modifyre=savedomtoxml.modifyDocument(new File("H:/dom4j/rt/orginal.xml"));
System.out.println(modifyre);
}
catch(Exception e)
{System.out.println(e.getMessage());}
}
}
|