dom4j為一個XML文檔在內存中創建了一個樹對象模型。 它提供了一組強大易用的API,通過XPath和XSLT來處理、操縱或者遍歷XML文件,此外其中還集成了SAX、JAXP和DOM。
為了提供高度可配置的實現策略,dom4j基於接口設計。只需要提供一個DocumentFactory實現,您就可以創建您自己的XML樹實現。這種設計,使得在擴展dom4j以定制您需要的特性時,能非常簡單地重用dom4j的代碼。
本文檔將通過代碼實例的方式為您提供一個dom4j的實踐指南。在實驗室項目中,這個開源工具包給我的工作帶來了很大的便利,在這篇文章中,我將對項目中用到dom4j完成的任務做個總結,以期和互聯網上的眾多文檔能夠互相補充。
讀取XML文件
一般性地讀取XML文件,在dom4j中操作起來將非常簡單。
public void readXMLSimple(File file) throws DocumentException{
//使用SAXReader讀取XML文件
SAXReader sr = new SAXReader();
Document doc = sr.read(file);
//使用XPath遍歷一個XML文件的結點
Element root = doc.getRootElement();
List entryList1 = root.selectNodes("entry");
//或者
List entryList2 = doc.selectNodes("/feed/entry");
}
創建一個XML文檔並記錄到磁盤上
創建一個XML文件,並將其寫到磁盤上,也可以使用非常簡介的代碼來完成,假設我們將上一個代碼范例中得到的entry節點的列表,插入到一個新建的XML文檔中,然後使用優美的縮進格式保存在磁盤上,我們可以像下面這樣編碼:
public void createXMLSimple(List entrIEs, File f)
throws FileNotFoundException,
UnsupportedEncodingException,
IOException{
Document doc = DocumentHelper.createDocument();
doc.addElement("feed");
Element root = doc.getRootElement();
Iterator i = entrIEs.iterator();
while(i.hasNext()){
//從別的Dom中得到的Element都有其本身
//的root,所以必須創建副本才能插入另一個doc內
root.add(((Element)i.next()).createCopy());
}
FileOutputStream os = new FileOutputStream(f);
OutputFormat of = OutputFormat.createPrettyPrint();
XMLWriter xmlw = new XMLWriter(os,of);
XMLw.write(doc);
}
讀取一個根節點帶有默認Namespace的XML
如果我們剛才的代碼范例讀取的是符合Atom1.0標准的Feed,那麼,根節點帶有default namespace的http://www.w3.org/2005/Atom。讀取這樣的XML文檔稍微有點麻煩,網上的代碼很多,但是很多都不好用,我總結下來,基本上沒有辦法像你想的那麼干淨。
public void treatDefaultNamespace(File f)
throws DocumentException{
SAXReader sr = new SAXReader();
Map ns = new HashMap();
ns.put("atom", "http://www.w3.org/2005/Atom");
sr.getDocumentFactory().setXPathNamespaceURIs(ns);
//Element接口支持迭代器,在這裡順便展示一下
Element root = sr.read(f).getRootElement();
Iterator i = root.elementIterator();
while(i.hasNext()){
Element e = (Element) i.next();
//一旦指定了Namespace,則使用XPath的時候必須帶上
//即便是默認的Namespace也一樣,不過前面那個名字
//可以盡可能寫得短,編碼的時候方便,比如改成a
String title = e.selectSingleNode("atom:title").getText();
System.out.println(title);
}
}
創建一個根節點帶有默認Namespace的XML
創建一個帶有default namespace的XML的方法,相當的tricky,因為你創建一個Element的方法有很多種,可以通過add方法,默認的建,也可以使用DocumentHelper對象來創建,不過,每種方法給你的結果都不同,往往讓你大吃一驚。其他的那些方法,和得到的多種結果,大家可以在網上看,很多。我就提供一個能創建“干淨”的XML的代碼范例。
public void createXMLWithDefaultNamespace(List entrIEs){
Document d = DocumentHelper.createDocument();
d.addElement("feed","http://www.w3.org/2005/Atom");
Element root = d.getRootElement();
//省略迭代entrIEs代碼
root.addElement("title").add(DocumentHelper.createCDATA(title));
root.addElement("id").add(DocumentHelper.createText(guid));
root.addElement("category").add(DocumentHelper.createText(category));
root.addElement("link").add(DocumentHelper.createText(permalink));
root.addElement("updated").add(DocumentHelper.createText(updated));
}
最後,羅列一下上文中用到的所有對象所在的包,沒有列出的在J2SE內。
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;