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

Java dom4j 解析 XML 實戰指南:核心 API 與最佳實踐

     編輯:Java 程式設計入門

dom4j 簡介

dom4j 是 Java 平台上優秀的開源 XML 解析庫,靈活性高、API 直觀、性能優異,支持 XPath、XSLT、Schema 驗證等高級特性。本文系統梳理 dom4j 核心用法,幫助開發者快速上手 XML 處理。

環境準備

<dependency>
    <groupId>org.dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>2.1.4</version>
</dependency>

核心操作全流程

1. 讀取並解析 XML 文檔

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import java.io.File;

public Document parseXml(String filePath) throws DocumentException {
    SAXReader reader = new SAXReader();
    // 支持 File、InputStream、URL、Reader 等多種數據源
    Document document = reader.read(new File(filePath));
    // 讀取時自動按 XML 聲明編碼轉換,亂碼問題通常源於編碼聲明與實際不符
    return document;
}

2. 獲取根元素

import org.dom4j.Element;

Element root = document.getRootElement();
// 根元素是整個 XML 文檔的入口,所有節點遍歷從此開始

3. 三種節點遍歷方式

方式一:Iterator 遍歷所有子元素


for (Iterator<Element> it = root.elementIterator(); it.hasNext(); ) {
    Element element = it.next();
    // 處理元素...
}

方式二:按元素名稱篩選遍歷


// 僅遍歷名為 "book" 的子元素
for (Iterator<Element> it = root.elementIterator("book"); it.hasNext(); ) {
    Element book = it.next();
    // 處理 book 元素...
}

方式三:屬性遍歷


for (Iterator<Attribute> it = root.attributeIterator(); it.hasNext(); ) {
    Attribute attr = it.next();
    System.out.println(attr.getName() + " = " + attr.getValue());
}

4. 便捷 List API(推薦現代寫法)


import java.util.List;

// 獲取所有直接子元素
List<Element> children = root.elements();

// 獲取指定名稱的子元素列表
List<Element> books = root.elements("book");

// 核心屬性獲取方法
String elementName = element.getName();           // 元素名稱
String elementText = element.getText();           // 文本內容(含子元素文本)
String elementTextTrim = element.getTextTrim();   // 去除首尾空白
Attribute attr = element.attribute("id");         // 獲取指定屬性對象
String attrValue = element.attributeValue("id");  // 直接獲取屬性值(安全,不拋 NPE)

實戰案例:解析書籍目錄 XML

示例 XML (books.xml)

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
    <book id="bk101" category="programming">
        <title>Java 核心技術</title>
        <author>Cay Horstmann</author>
        <price currency="CNY">128.00</price>
        <publish_date>2023-03-15</publish_date>
    </book>
    <book id="bk102" category="database">
        <title>MySQL 實戰 45 講</title>
        <author>林曉斌</author>
        <price currency="CNY">89.90</price>
        <publish_date>2022-11-20</publish_date>
    </book>
</catalog>

解析代碼


public void parseBooks(String xmlPath) throws DocumentException {
    Document doc = parseXml(xmlPath);
    Element root = doc.getRootElement();
    
    List<Element> books = root.elements("book");
    for (Element book : books) {
        String id = book.attributeValue("id");
        String category = book.attributeValue("category");
        String title = book.elementText("title");
        String author = book.elementText("author");
        String price = book.elementText("price");
        String currency = book.element("price").attributeValue("currency");
        String pubDate = book.elementText("publish_date");
        
        System.out.printf("【%s】%s / %s / %s %s (%s)%n", id, title, author, price, currency, pubDate);
    }
}

進階技巧與最佳實踐

1. XPath 強大查詢


// 選擇所有價格 > 100 的書籍
List<Node> expensiveBooks = document.selectNodes("//book[price > 100]");
// 獲取第一本書的作者
String firstAuthor = document.selectSingleNode("//book[1]/author").getText();

2. 編碼問題排查

  • 確保 XML 文件頭聲明編碼:<?xml version="1.0" encoding="UTF-8"?>
  • 讀取 InputStream 時可指定編碼:reader.read(inputStream, "UTF-8")
  • 寫入文件時設置輸出格式:OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("UTF-8");

3. 內存優化:大文件流式處理

對於超大 XML(>100MB),DOM 模型會導致 OOM。dom4j 提供 SAXReader 配合 ElementHandler 實現邊讀邊處理:


SAXReader reader = new SAXReader();
reader.addElementHandler("/catalog/book", new ElementHandler() {
    @Override
    public void onStart(ElementPath path) {}
    
    @Override
    public void onEnd(ElementPath path) {
        Element book = path.getCurrent();
        // 處理單個 book 元素
        processBook(book);
        // 關鍵:處理完立即釋放內存
        path.getCurrent().detach();
    }
});
reader.read(new File("huge.xml"));

4. 命名空間處理


// 註冊命名空間前綴
Map<String, String> nsMap = new HashMap<>();
nsMap.put("ns", "https://example.com/namespace");
XPath xpath = document.createXPath("//ns:book");
xpath.setNamespaceURIs(nsMap);

常見坑點總結

問題原因解決方案
getText() 返回空串元素包含子元素,文本在子節點中使用 elementText() 或遍歷 textNodes()
屬性值獲取拋 NPEattribute() 返回 null 時調用 getValue()改用 attributeValue() 安全獲取
中文亂碼文件實際編碼與聲明不一致統一使用 UTF-8,或指定編碼讀取
大文件 OOMDOM 全量加載進內存使用 ElementHandler 流式處理

總結

dom4j 以靈活的 API 和豐富的功能成為 Java XML 處理的首選。掌握基本遍歷、XPath 查詢、流式處理、命名空間等核心技能,能應對 95% 的 XML 業務場景。建議在新項目中考慮更現代的 Jackson XML 或 JAXB 實現對象綁定,進一步提升開發效率。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved