DOM (Document Object Model) 將 XML 文件載入記憶體形成樹狀結構,節點即物件,適合頻繁隨機存取、修改文件結構的場景。本文從 JAXP 標準 API 切入,完整示範解析、遍歷、建立 XML 的核心技術。
JAXP (Java API for XML Processing) 提供廠商中立的解析器介面,透過工廠模式隔離具體實作 (Xerces、Crimson 等)。核心三步驟:
// 1. 取得工廠
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 2. 取得解析器
DocumentBuilder builder = factory.newDocumentBuilder();
// 3. 解析文件 -> Document 物件 (樹根)
Document doc = builder.parse("path/to/file.xml");
| 介面 | 角色 | 常用方法 |
|---|---|---|
| Document | 整份文件根節點 | createElement、createTextNode、getElementsByTagName、getDocumentElement |
| Element | 標籤元素 | getAttribute、setAttribute、getElementsByTagName、appendChild |
| Node | 所有節點超介面 | getNodeType、getNodeName、getNodeValue、getFirstChild、getChildNodes、appendChild |
| NodeList | 節點有序集合 | getLength、item(index) |
| Attr | 屬性節點 | getName、getValue |
| Text | 文字內容節點 | getData、setData |
範例 XML:
<?xml version="1.0" encoding="UTF-8"?>
<messages>
<message>Good-bye serialization, hello Java!</message>
</messages>
提取 <message> 文字:
NodeList list = doc.getElementsByTagName("message");
if (list.getLength() > 0) {
Node msgNode = list.item(0);
// 文字內容在第一個子節點 (Text 節點)
String text = msgNode.getFirstChild().getNodeValue();
System.out.println(text); // Good-bye serialization, hello Java!
}
關鍵: W3C 規範將元素內的文字也視為獨立的 Text 節點,故必須先 getFirstChild() 再取值。
// 建立新文件
Document newDoc = builder.newDocument();
Element root = newDoc.createElement("books");
newDoc.appendChild(root);
Element book = newDoc.createElement("book");
book.setAttribute("isbn", "978-7-111-12345-6");
root.appendChild(book);
Element title = newDoc.createElement("title");
title.appendChild(newDoc.createTextNode("Effective Java"));
book.appendChild(title);
// 輸出為檔案 (需搭配 Transformer)
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(new DOMSource(newDoc), new StreamResult(new File("books.xml")));
factory.setNamespaceAware(true),查詢時使用 getElementsByTagNameNS。Text 節點分割:相鄰文字可能被拆分為多個 Text 節點,讀取前呼叫 element.normalize() 合併。factory.setIgnoringElementContentWhitespace(true) 需配合 DTD/Schema 驗證才生效。掌握 DOM 操作是 Java XML 開發的基石,搭配 XPath (JAXP 1.3+) 更能如虎添翼。下一步可探索 SAX 事件驅動解析與 StAX 流式處理,構建完整 XML 技術棧。