首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

XML 程式設計總結 (四):dom4j 核心用法與 XPath 整合實戰

     編輯:Java 綜合教學

XML 程式設計總結 (四):dom4j 核心用法與 XPath 整合實戰

dom4j 是基於 Java 的開源 XML 框架,以介面導向設計、極致易用性、原生 XPath 支援 著稱,效能優於 Sun 官方 DOM 實作。本文涵蓋核心 API、常見操作模式、XPath 查詢、命名空間處理與效能優化建議。

一、核心依賴與架構

<dependency>
    <groupId>org.dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>2.1.4</version> <!-- 最新穩定版 -->
</dependency>
<!-- XPath 需額外引入 jaxen -->
<dependency>
    <groupId>jaxen</groupId>
    <artifactId>jaxen</artifactId>
    <version>1.2.0</version>
</dependency>

核心介面體系:Document、Element、Attribute、Node 皆為介面,實作類由 DocumentFactory 建立,支援可插拔實作。

二、基礎讀寫操作範本

1. 解析 XML 文件/字串/輸入流

SAXReader reader = new SAXReader();
// 開啟驗證 (需 XSD/DTD)
reader.setValidation(true);
reader.setEntityResolver(new MyEntityResolver());

Document doc = reader.read(new File("books.xml"));
// 或
Document doc = reader.read(new StringReader(xmlString));
Document doc = reader.read(inputStream);

2. 遍歷節點樹

// 根元素
Element root = doc.getRootElement(); // 

// 遞迴遍歷 (DOM 風格)
void traverse(Element element) {
    for (Iterator<Element> it = element.elementIterator(); it.hasNext(); ) {
        Element child = it.next();
        System.out.println(child.getName() + " = " + child.getTextTrim());
        traverse(child);
    }
}

// 或使用 XPath 一次到位 (見下節)

3. 建立/修改/刪除節點

Document doc = DocumentHelper.createDocument();
Element root = doc.addElement("bookstore");

Element book = root.addElement("book")
    .addAttribute("category", "JAVA");
book.addElement("title").addAttribute("lang", "zh").setText("Effective Java");
book.addElement("author").setText("Joshua Bloch");
book.addElement("price").setText("59.00");

// 修改
Element title = book.element("title");
title.setText("Effective Java 3rd Edition");

// 刪除
book.element("author").detach(); // 或 title.getParent().remove(title);

// 輸出格式化
OutputFormat fmt = OutputFormat.createPrettyPrint();
fmt.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileOutputStream("out.xml"), fmt);
writer.write(doc);
writer.close();

三、XPath 強力查詢 (需 jaxen.jar)

基本語法速查

表達式含義
//book所有 book 元素 (任意深度)
/bookstore/book[1]第一個 book 子元素
//book[@category='WEB']category 屬性為 WEB 的 book
//book/title/@lang所有 title 的 lang 屬性值
//book[price < 40]價格小於 40 的 book

實戰代碼

// 編譯 XPath (可重複使用)
XPath xpath = doc.createXPath("//book[@category='WEB']/title");

// 單節點查詢
Node titleNode = xpath.selectSingleNode(doc);
System.out.println(titleNode.getText()); // "XQuery Kick Start"

// 節點集合查詢
List<Node> titles = xpath.selectNodes(doc);
for (Node n : titles) System.out.println(n.getText());

// 直接取文字內容
String price = doc.valueOf("//book[@category='COOKING']/price"); // "30.00"

// 取屬性值
String lang = doc.valueOf("//book[1]/title/@lang"); // "en"

// 計數
Number count = (Number) xpath.evaluate("count(//book)", doc); // 4.0

四、命名空間處理 (實戰必備)

XML 若含命名空間,XPath 必須 註冊前綴映射,否則查無結果。

<root xmlns:ns="https://example.com/ns">
    <ns:item>value</ns:item>
</root>
Map<String, String> nsMap = new HashMap<>();
nsMap.put("ns", "https://example.com/ns");
XPath xpath = doc.createXPath("//ns:item");
xpath.setNamespaceURIs(nsMap); // 關鍵步驟
Node node = xpath.selectSingleNode(doc);

五、效能優化與最佳實踐

  1. 重用 SAXReader:線程安全,全局單例。
  2. 大文檔用 StAX/SAX:dom4j 同屬 DOM 樹模型,記憶體隨文檔增長,超過 50MB 建議改用 StAX 流式處理。
  3. XPath 編譯緩存:XPath 物件可重用,避免重複編譯正則。
  4. 寫入大文件:用 XMLStreamWriter (StAX) 邊生成邊輸出,而非建立完整 Document 樹。
  5. 關閉 DTD 驗證:生產環境 reader.setValidation(false) 避免網路下載 DTD 導致卡頓。

六、常見坑點

  • element.getText() 返回所有子孫文字內容拼接,單純取當前元素文字請用 element.getTextTrim() 或 element.node(0).getText()。
  • detach() 移除節點後,該節點仍可操作但不再屬於樹,若需彻底丟棄請置 null。
  • 預設 SAXReader 不支援 XML 1.1,需 reader.setFeature("https://apache.org/xml/features/allow-java-encodings", true)。
  • 輸出時 OutputFormat.setExpandEmptyElements(true) 讓空元素輸出 <tag></tag> 而非 <tag/>,相容舊系統。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved