DOM (Document Object Model) 是 W3C 標準,提供對 HTML/XML 文檔的結構化物件模型與操作介面。PHP 內建 DOMDocument、DOMXPath 等類別,支援載入、驗證、查詢、修改、建立、序列化 XML。屬於樹狀解析器,將整份文檔載入記憶體形成節點樹。
PHP 核心內建,無需安裝。
| 類別/方法 | 說明 |
|---|---|
new DOMDocument() | 建立文檔物件 |
load($file) | 從檔案載入 XML |
loadXML($string) | 從字串載入 XML |
save($file) / saveXML() | 儲存至檔案 / 返回 XML 字串 |
validate() | 依 DTD 驗證 |
schemaValidate($xsd) | 依 XSD 驗證 |
getElementsByTagName($name) | 取得元素節點列表 (DOMNodeList) |
createElement($name, $value) | 建立元素節點 |
createAttribute($name) | 建立屬性節點 |
createTextNode($text) | 建立文字節點 |
appendChild($node) | 新增子節點 |
insertBefore($new, $ref) | 在參考節點前插入 |
removeChild($node) | 移除子節點 |
replaceChild($new, $old) | 替換子節點 |
normalize() | 合併相鄰文字節點 |
new DOMXPath($doc) — 建立 XPath 查詢器query($expression) — 執行 XPath 查詢,返回 DOMNodeListevaluate($expression) — 執行 XPath 表達式,可返回標量值registerNamespace($prefix, $uri) — 註冊命名空間前綴<?xml version="1.0" encoding="ISO-8859-1"?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
<?php
$doc = new DOMDocument();
$doc->load('note.xml');
echo $doc->saveXML();
?>
<?php
$doc = new DOMDocument();
$doc->load('note.xml');
$root = $doc->documentElement; //
foreach ($root->childNodes as $node) {
if ($node->nodeType === XML_ELEMENT_NODE) {
echo $node->nodeName . ' = ' . $node->nodeValue . '<br>';
}
}
/* 輸出:
to = Tove
from = Jani
heading = Reminder
body = Don't forget me this weekend!
*/
?>
<?php
$doc = new DOMDocument();
$doc->load('books.xml');
$xpath = new DOMXPath($doc);
$titles = $xpath->query('//book[@category="php"]/title');
foreach ($titles as $title) {
echo $title->nodeValue . '<br>';
}
?>
<?php
$doc = new DOMDocument('1.0', 'UTF-8');
$root = $doc->createElement('catalog');
$doc->appendChild($root);
$book = $doc->createElement('book');
$book->setAttribute('id', '1');
$root->appendChild($book);
$title = $doc->createElement('title', 'PHP Mastery');
$book->appendChild($title);
$author = $doc->createElement('author');
$author->appendChild($doc->createTextNode('John Doe'));
$book->appendChild($author);
echo $doc->saveXML();
?>
<?php
$doc = new DOMDocument();
$doc->load('note.xml');
$xpath = new DOMXPath($doc);
$toNode = $xpath->query('//to')->item(0);
if ($toNode) {
$toNode->nodeValue = 'Anna';
}
$dateNode = $doc->createElement('date', '2024-01-15');
$doc->documentElement->appendChild($dateNode);
$doc->save('note_updated.xml');
?>
<?php
$doc = new DOMDocument();
$doc->load('ns.xml');
$xpath = new DOMXPath($doc);
$xpath->registerNamespace('dc', 'https://purl.org/dc/elements/1.1/');
$creators = $xpath->query('//dc:creator');
foreach ($creators as $c) {
echo $c->nodeValue . '<br>';
}
?>
XML 格式化時的縮排、換行會產生 #text 空白節點。遍歷時請檢查 $node->nodeType === XML_ELEMENT_NODE (值為 1) 以過濾純元素節點,或呼叫 $doc->preserveWhiteSpace = false; $doc->formatOutput = true; 配合 normalize() 整理。
| 場景 | 推薦 | 理由 |
|---|---|---|
| 簡單讀取/修改小型 XML | SimpleXML | 語法最簡潔 |
| 複雜查詢、XPath、命名空間、結構修改 | DOMDocument | 功能最完整、符合標準 |
| 大型 XML (超過記憶體)、單向串流讀取 | XMLReader | 低記憶體、高效能 |
| SAX 風格事件驅動解析 | XML Parser (Expat) | 回呼式、不建樹 |