文件物件模型 (DOM) 將 XML 文件在記憶體中表示為一棵節點樹。每個元素、屬性、文字都是一個節點 (`Node`)。Java 標準庫 (`javax.xml.parsers`, `org.w3c.dom`) 實作了 DOM Level 3 Core 規範,提供平台獨立的 XML 操作 API。
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true); // 建議開啟命名空間感知
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new File("input.xml")); // 也可傳入 InputStream
遞迴深度優先走訪是最通用的方式:
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);
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);
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);