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

Java DOM 解析 XML 實戰:從入門到放棄(及更好的替代方案)

     編輯:Java 程式設計入門

DOM 解析器:適合「小而全」的場景

DOM (Document Object Model) 解析器會一次性將整個 XML 文檔加載到內存,構建一棵完整的文檔對象樹。優點是操作直觀、支持隨機訪問、增刪改查靈活;缺點是內存佔用大,不適合大文件(>50MB 易 OOM)。正如原文吐槽:「代碼丑到吐」,這正是 JDOM、Dom4j、XStream 等封裝庫誕生的原因。

核心 API 速查

接口/類核心作用
DocumentBuilderFactory解析器工廠,獲取 DocumentBuilder
DocumentBuilder執行解析,生成 Document 對象
Document文檔樹根節點,代表整個 XML 文檔
Element元素節點,可獲取屬性、子元素、文本內容
NodeList節點列表,按文檔順序存儲
NamedNodeMap屬性集合,非有序

實戰代碼:解析書籍目錄 XML

假設 books.xml 結構如下:

<books>
  <book id="1" category="tech">
    <title>Effective Java</title>
    <author>Joshua Bloch</author>
  </book>
  <book id="2" category="novel">
    <title>Three Body</title>
    <author>Liu Cixin</author>
  </book>
</books>

標準 DOM 解析流程

public class DomParserDemo {
    public static void main(String[] args) throws Exception {
        // 1. 獲取工廠與解析器
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        // 建議開啟命名空間感知,生產環境必開
        factory.setNamespaceAware(true); 
        DocumentBuilder builder = factory.newDocumentBuilder();

        // 2. 解析文件 -> Document 對象(全量加載入內存)
        Document doc = builder.parse(new File("books.xml"));

        // 3. 獲取根元素
        Element root = doc.getDocumentElement(); // 

        // 4. 獲取所有 book 元素
        NodeList bookList = root.getElementsByTagName("book");

        // 5. 遍歷提取數據
        for (int i = 0; i < bookList.getLength(); i++) {
            Element book = (Element) bookList.item(i);
            
            // 5.1 獲取屬性
            String id = book.getAttribute("id");
            String category = book.getAttribute("category");
            
            // 5.2 獲取子元素文本(繞彎路:Element -> NodeList -> Node -> getTextContent)
            String title = book.getElementsByTagName("title").item(0).getTextContent();
            String author = book.getElementsByTagName("author").item(0).getTextContent();
            
            System.out.printf("ID: %s | 類別: %s | 書名: %s | 作者: %s%n", 
                id, category, title, author);
        }
    }
}

輸出結果

ID: 1 | 類別: tech | 書名: Effective Java | 作者: Joshua Bloch
ID: 2 | 類別: novel | 書名: Three Body | 作者: Liu Cixin

DOM 痛點與優化技巧

痛點 1:獲取文本太繁瑣

標準 DOM 需鏈式調用:getElementsByTagName -> item(0) -> getTextContent()。封裝工具方法:

private String getChildText(Element parent, String tagName) {
    NodeList list = parent.getElementsByTagName(tagName);
    return list.getLength() > 0 ? list.item(0).getTextContent() : "";
}

痛點 2:內存溢出風險

大文件解析建議:

  • 啟用 factory.setExpandEntityReferences(false) 禁用實體擴展。
  • 或改用 SAX/StAX 流式解析(內存常數級)。

痛點 3:增刪改代碼極其冗長

創建元素需:doc.createElement -> setAttribute -> appendChild -> doc.createTextNode -> appendChild。這正是第三方庫簡化的重點。

現代替代方案推薦

庫特點適用場景
Dom4jXPath 支持、鏈式 API、性能優於 DOM企業級項目、複雜 XML 處理
JDOM2純 Java 設計、API 直觀、泛型支持中小型項目、追求代碼可讀性
XStream對象<->XML 雙向轉換、註解驅動配置文件、數據序列化
JAXB標準規範、註解映射、Schema 驗證Web Service、標準化數據交換

Dom4j 快速上手示例

// Maven: org.dom4j:dom4j:2.1.3
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("books.xml"));

// XPath 一鍵提取
List books = doc.selectNodes("//book");
for (Node book : books) {
    String title = book.selectSingleNode("title").getText();
    String author = book.selectSingleNode("author").getText();
    String id = book.valueOf("@id"); // 屬性快速取值
    System.out.println(id + " | " + title + " | " + author);
}

總結

標準 DOM API 是理解 XML 模型的基石,但實際開發中請直接使用 Dom4j 或 JDOM2。僅在「無法引入第三方依賴」、「文件極小(<100KB)」、「需零依賴運行」的受限環境下,才考慮手寫原生 DOM 代碼。記住:工具是為業務服務的,別在 API 細節裡迷失。

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