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

Java DOM 解析 XML 完整教學:讀取、查詢、修改、寫回實戰

     編輯:Java 綜合教學

DOM 解析器建立與載入

public static Document getDocument(String filename) throws Exception {
    // 1. 建立工廠
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    // 2. 取得 DOM 解析器
    DocumentBuilder builder = factory.newDocumentBuilder();
    // 3. 解析 XML 檔案,回傳 Document 物件樹
    return builder.parse(filename);
}

範例 XML 結構 (books.xml)


<書架>
    <書>
        <書名 name="xxx">Java就業培訓教程
        <作者>張孝祥
        <售價>59.00元
    
    <書>
        <書名>JavaScript網頁開發
        <作者>張孝祥
        <售價>28.00元
    

核心操作 API

1. 讀取單一節點

NodeList list = document.getElementsByTagName("書名");
Node node = list.item(1); // 索引 1 = 第二本書
String content = node.getTextContent();
System.out.println(content); // 輸出:JavaScript網頁開發

2. 遞迴遍歷所有節點

Node root = document.getElementsByTagName("書架").item(0);
printNode(root, 0);

void printNode(Node node, int depth) {
    if (node instanceof Element) {
        System.out.println("  ".repeat(depth) + node.getNodeName());
    }
    NodeList children = node.getChildNodes();
    for (int i = 0; i < children.getLength(); i++) {
        printNode(children.item(i), depth + 1);
    }
}

3. 取得屬性值

Element bookName = (Element) document.getElementsByTagName("書名").item(0);
String attrValue = bookName.getAttribute("name"); // "xxx"
System.out.println(attrValue);

4. 新增節點 (附加到第一本書)

// 建立新元素
Element price = document.createElement("售價");
price.setTextContent("59.00元");

// 掛載到目標父節點
Element book = (Element) document.getElementsByTagName("書").item(0);
book.appendChild(price);

// 寫回檔案
writeBack(document, filename);

5. 指定位置插入 (在第一個 <售價> 前插入)

Element price = document.createElement("售價");
price.setTextContent("49.00元");

Element refNode = (Element) document.getElementsByTagName("售價").item(0);
Element book = (Element) document.getElementsByTagName("書").item(0);
book.insertBefore(price, refNode); // 插入到 refNode 之前

writeBack(document, filename);

6. 設定/修改屬性

Element bookName = (Element) document.getElementsByTagName("書名").item(0);
bookName.setAttribute("name", "xxxxxx"); // 新增或更新屬性
writeBack(document, filename);

7. 刪除節點

Element priceNode = (Element) document.getElementsByTagName("售價").item(0);
priceNode.getParentNode().removeChild(priceNode);
writeBack(document, filename);

通用寫回工具方法

private static void writeBack(Document doc, String filename) throws Exception {
    TransformerFactory tfFactory = TransformerFactory.newInstance();
    Transformer transformer = tfFactory.newTransformer();
    transformer.setOutputProperty(OutputKeys.INDENT, "yes"); // 格式化縮排
    transformer.setOutputProperty("{https://xml.apache.org/xslt}indent-amount", "4");
    transformer.transform(
        new DOMSource(doc), 
        new StreamResult(new FileOutputStream(filename))
    );
}

DOM vs SAX vs StAX 選擇指南

解析器模式記憶體速度適用場景
DOM樹狀模型 (整份載入記憶體)高中需隨機存取、修改結構、文件較小 (<50MB)
SAX事件驅動 (串流單向)極低快唯讀、大檔案、記憶體受限、只需特定資料
StAX拉取式 (游標控制)低快需控制解析流程、雙向操作、大檔案處理

常見坑點提醒

  • getChildNodes() 包含文字節點 (換行、空白),遍歷時需檢查 node.getNodeType() == Node.ELEMENT_NODE
  • getTextContent() 會遞迴串聯所有子文字節點,getNodeValue() 僅取得當前節點值
  • 命名空間 XML 需啟用 factory.setNamespaceAware(true) 並使用 getElementsByTagNameNS
  • 大檔案請改用 SAX/StAX,DOM 會造成 OOM
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved