Dom4j的使用(Dom4j對xml的解析即增刪改查)
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吧。
Attribute定義了XML的屬性 | |
Branch為能夠包含子節點的節點如XML元素(Element)和文檔(Docuemnts)定義了一個公共的行為, | |
CDATA 定義了XML CDATA 區域 | |
CharacterData是一個標識借口,標識基于字符的節點。如CDATA,Comment, Text. | |
Comment 定義了XML注釋的行為 | |
定義了XML文檔 | |
DocumentType 定義XML DOCTYPE聲明 | |
Element定義XML 元素 | |
ElementHandler定義了 Element 對象的處理器 | |
被 ElementHandler 使用,用于取得當前正在處理的路徑層次信息 | |
Entity定義 XML entity | |
Node為所有的dom4j中XML節點定義了多態行為 | |
NodeFilter 定義了在dom4j節點中產生的一個濾鏡或謂詞的行為(predicate) | |
ProcessingInstruction 定義 XML 處理指令. | |
Text 定義XML 文本節點. | |
Visitor 用于實現Visitor模式. | |
XPath 在分析一個字符串后會提供一個XPath 表達式 |
- interface java.lang.Cloneable
- interface org.dom4j.Node
-
-
- interface org.dom4j.CharacterData
- interface org.dom4j.CDATA
- interface org.dom4j.DocumentType
- interface org.dom4j.Entity
- interface org.dom4j.ProcessingInstruction
-
一、 讀取并解析XML文檔:
// 從文件讀取XML,輸入文件名,返回XML文檔
public Document read(String fileName) throws MalformedURLException, DocumentException {
SAXReader reader = new SAXReader();
Document document = reader.read(new File(fileName));
return document;
}
|
public Element getRootElement(Document doc){
return doc.getRootElement();
}
|
三、 遍歷XML樹(三種方法)
1)枚舉:
// 枚舉所有子節點
for ( Iterator i = root.elementIterator(); i.hasNext(); ) {
Element element = (Element) i.next();
// do something
}
// 枚舉名稱為foo的節點
for ( Iterator i = root.elementIterator(foo); i.hasNext();) {
Element foo = (Element) i.next();
// do something
}
// 枚舉屬性
for ( Iterator i = root.attributeIterator(); i.hasNext(); ) {
Attribute attribute = (Attribute) i.next();
// do something
} |
public void treeWalk() {
treeWalk(getRootElement());
}
public void treeWalk(Element element) {
for (int i = 0, size = element.nodeCount(); i < size; i++) {
Node node = element.node(i);
if (node instanceof Element) {
treeWalk((Element) node);
} else { // do something....
}
}
}
|
3)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是自動遍歷所有子節點的。如果是root.accept(MyVisitor),將遍歷子節點。
五、 字符串與XML的轉換
// XML轉字符串
Document document = ...;
String text = document.asXML();
// 字符串轉XML
String text =
Document document = DocumentHelper.parseText(text);
|
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;
}
|
public Document createDocument() {
Document document = DocumentHelper.createDocument();
Element root = document.addElement(root);
Element author1 =
root
.addElement(author)
.addAttribute(name, James)
.addAttribute(location, UK)
.addText(James Strachan);
Element author2 =
root
.addElement(author)
.addAttribute(name, Bob)
.addAttribute(location, US)
.addText(Bob McWhirter);
return document;
}
|
FileWriter out = new FileWriter( foo.xml );
document.write(out);
|
public void write(Document document) throws IOException {
// 指定文件
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 );
}
|
最后附上,我做測試一份簡單代碼:
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"));
}
}