dom4j 將 XML 文件在記憶體中建構為樹狀物件模型,提供強大易用的 API,支援 XPath、XSLT 查詢與轉換,並整合 SAX、JAXP、DOM。基於介面設計,透過 DocumentFactory 可自訂樹實作,擴充性極佳。
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;
public void readXMLSimple(File file) throws DocumentException {
SAXReader reader = new SAXReader();
Document doc = reader.read(file);
Element root = doc.getRootElement();
// XPath 查詢
List entries1 = root.selectNodes("entry");
// 或從文件根節點
List entries2 = doc.selectNodes("/feed/entry");
}
public void createXMLSimple(List entries, File f) throws IOException {
Document doc = DocumentHelper.createDocument();
doc.addElement("feed");
Element root = doc.getRootElement();
for (Object obj : entries) {
Element e = (Element) obj;
// 跨 Document 複製節點需用 createCopy()
root.add(e.createCopy());
}
FileOutputStream fos = new FileOutputStream(f);
OutputFormat fmt = OutputFormat.createPrettyPrint(); // 優美縮排
XMLWriter writer = new XMLWriter(fos, fmt);
writer.write(doc);
writer.close();
}
Atom 1.0 Feed 根節點宣告 xmlns="https://www.w3.org/2005/Atom",直接用 XPath 查詢會失敗,必須註冊前綴對應 URI。
public void treatDefaultNamespace(File f) throws DocumentException {
SAXReader reader = new SAXReader();
Map<String, String> nsMap = new HashMap<>();
nsMap.put("atom", "https://www.w3.org/2005/Atom");
reader.getDocumentFactory().setXPathNamespaceURIs(nsMap);
Element root = reader.read(f).getRootElement();
for (Iterator it = root.elementIterator(); it.hasNext(); ) {
Element e = (Element) it.next();
// XPath 必須帶上前綴
String title = e.selectSingleNode("atom:title").getText();
System.out.println(title);
}
}
關鍵:使用 DocumentHelper.createDocument() 並以兩參數 addElement(name, namespaceURI) 建立根節點,後續子節點會自動繼承命名空間,產出「乾淨」的 XML(無冗餘前綴)。
public void createXMLWithDefaultNamespace(List entries) {
Document doc = DocumentHelper.createDocument();
// 根節點指定命名空間 URI
Element root = doc.addElement("feed", "https://www.w3.org/2005/Atom");
// 範例:新增 entry 結構
Element entry = root.addElement("entry");
entry.addElement("title").add(DocumentHelper.createCDATA("標題內容"));
entry.addElement("id").add(DocumentHelper.createText("urn:uuid:12345"));
entry.addElement("category").add(DocumentHelper.createText("tech"));
entry.addElement("link").add(DocumentHelper.createText("https://example.com"));
entry.addElement("updated").add(DocumentHelper.createText("2024-01-01T00:00:00Z"));
// 輸出...
}
| 需求 | API / 寫法 |
|---|---|
| 建立 CDATA 區段 | DocumentHelper.createCDATA(text) |
| 建立純文字節點 | DocumentHelper.createText(text) |
| 跨 Document 移動節點 | element.createCopy() 再 add() |
| 輸出格式化 | OutputFormat.createPrettyPrint() |
| 指定編碼 | OutputFormat.setEncoding("UTF-8") |
| 啟用 XPath 變數 | XPath.setVariableContext(context) |
dom4j 以直覺 API、完整 XPath/XSLT 支援、靈活的 DocumentFactory 設計,成為 Java 處理 XML 的首選工具之一。掌握命名空間處理與跨 Document 節點複製技巧,可避開常見坑點,高效完成 XML 讀寫與轉換任務。