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

Java DOM 解析器完全指南:XML 與 DOM 文件雙向轉換實戰

     編輯:Java 相關知識

核心概念:什麼是 DOM?

文件物件模型 (DOM) 將 XML 文件在記憶體中表示為一棵節點樹。每個元素、屬性、文字都是一個節點 (`Node`)。Java 標準庫 (`javax.xml.parsers`, `org.w3c.dom`) 實作了 DOM Level 3 Core 規範,提供平台獨立的 XML 操作 API。

四大核心操作步驟

1. XML → DOM (解析)

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true); // 建議開啟命名空間感知
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new File("input.xml")); // 也可傳入 InputStream

2. 遍歷 DOM 樹

遞迴深度優先走訪是最通用的方式:

void traverse(Node node, int depth) {
    String indent = "  ".repeat(depth);
    System.out.println(indent + node.getNodeName() + " (" + node.getNodeType() + ")");
    if (node.getNodeType() == Node.ELEMENT_NODE) {
        Element el = (Element) node;
        if (el.hasAttributes()) {
            NamedNodeMap attrs = el.getAttributes();
            for (int i = 0; i < attrs.getLength(); i++) {
                Node attr = attrs.item(i);
                System.out.println(indent + "  @" + attr.getNodeName() + "=" + attr.getNodeValue());
            }
        }
    } else if (node.getNodeType() == Node.TEXT_NODE) {
        String text = node.getNodeValue().trim();
        if (!text.isEmpty()) System.out.println(indent + "  #text: " + text);
    }
    NodeList children = node.getChildNodes();
    for (int i = 0; i < children.getLength(); i++) {
        traverse(children.item(i), depth + 1);
    }
}
// 呼叫入口
traverse(doc.getDocumentElement(), 0);

3. 修改 DOM (增/刪/改)

Element root = doc.getDocumentElement();

// 新增元素
Element book = doc.createElement("book");
book.setAttribute("id", "bk101");
root.appendChild(book);

// 新增子元素與文字
Element title = doc.createElement("title");
title.appendChild(doc.createTextNode("Effective Java"));
book.appendChild(title);

// 修改現有節點
NodeList nl = doc.getElementsByTagName("price");
if (nl.getLength() > 0) {
    nl.item(0).setTextContent("45.00");
}

// 刪除節點
Node obsolete = doc.getElementById("oldBook");
if (obsolete != null) obsolete.getParentNode().removeChild(obsolete);

4. DOM → XML (序列化)

TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{https://xml.apache.org/xslt}indent-amount", "2");

DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("output.xml"));
transformer.transform(source, result);

效能考量與替代方案

  • DOM 缺點: 整份文件載入記憶體,大檔案易造成 OOM。
  • 替代方案:
    • SAX / StAX (javax.xml.stream): 事件驅動/拉取式流式處理,記憶體佔用極低,適合超大 XML。
    • JAXB / Jackson XML: 物件綁定 (O/X Mapping),開發效率最高,適合結構固定的資料交換。

常見坑點提醒

  1. 解析時若未設 `setNamespaceAware(true)`,XPath 查詢命名空間元素會失效。
  2. `Text` 節點會保留換行縮排,比較文字內容前請先 `trim()`。
  3. 序列化輸出編碼預設為 UTF-8,需透過 `OutputKeys.ENCODING` 指定其他編碼。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved