現代 PHP 使用 DOMDocument 操作 XML,提供標準化、記憶體安全的節點建立與插入 API。本文示範如何載入現有 XML、定位目標父節點、建立新元素與屬性、插入到指定位置,並正確輸出格式化 XML。
<?xml version="1.0" encoding="UTF-8"?>
<contact id="43956">
<personal>
<name>
<first>John</first>
<middle>Q</middle>
<last>Doe</last>
</name>
<title>Manager</title>
<employer>National</employer>
<dob>1971-12-22</dob>
</personal>
</contact>
<?php
$file = 'contacts.xml';
$dom = new DOMDocument();
$dom->preserveWhiteSpace = false; // 忽略原文縮排空白
$dom->formatOutput = true; // 輸出時自動縮排
$dom->load($file);
// 1. 定位目標父節點:用 XPath 更精準
$xpath = new DOMXPath($dom);
$personalNode = $xpath->query('/contact/personal')->item(0);
if (!$personalNode) {
die("找不到 節點");
}
// 2. 建立新元素節點
$workNode = $dom->createElement('work', '6666'); // 直接設定文字內容
// 3. 新增屬性(可選)
$workNode->setAttribute('department', 'engineering');
$workNode->setAttribute('since', '2023-01-15');
// 4. 插入為 的最後一個子節點
$personalNode->appendChild($workNode);
// 5. 也可插入到特定位置:例如在 之後
// $titleNode = $xpath->query('/contact/personal/title')->item(0);
// $personalNode->insertBefore($workNode, $titleNode->nextSibling);
// 6. 輸出結果
header('Content-Type: application/xml; charset=UTF-8');
echo $dom->saveXML();
// 或存檔
// $dom->save($file);
?>
<?xml version="1.0" encoding="UTF-8"?>
<contact id="43956">
<personal>
<name>
<first>John</first>
<middle>Q</middle>
<last>Doe</last>
</name>
<title>Manager</title>
<employer>National</employer>
<dob>1971-12-22</dob>
<work department="engineering" since="2023-01-15">6666</work>
</personal>
</contact>
| 方法 | 說明 | 回傳值 |
|---|---|---|
createElement($name, $value='') | 建立元素節點,可選設定文字內容 | DOMElement |
createTextNode($text) | 建立純文字節點(會自動跳脫特殊字元) | DOMText |
createAttribute($name) | 建立屬性節點 | DOMAttr |
createCDATASection($data) | 建立 CDATA 區塊 | DOMCDATASection |
appendChild($node) | 加入為最後一個子節點 | 插入的節點 |
insertBefore($new, $ref) | 在參考節點 $ref 之前插入 $new | 插入的節點 |
replaceChild($new, $old) | 以 $new 取代 $old | 被取代的舊節點 |
removeChild($node) | 移除子節點 | 被移除的節點 |
cloneNode($deep=true) | 複製節點(含子樹) | 新節點 |
setAttribute($name, $value) | 直接設定元素屬性(便利方法) | void |
<?php
// 建立 Taipei 100
$address = $dom->createElement('address');
$city = $dom->createElement('city', 'Taipei');
$zip = $dom->createElement('zip', '100');
$address->appendChild($city);
$address->appendChild($zip);
$personalNode->appendChild($address);
?>
<?php
// 註冊命名空間
$nsUri = 'https://example.com/ns';
$dom->documentElement->setAttribute('xmlns:ex', $nsUri);
// 建立帶命名空間的元素
$exNode = $dom->createElementNS($nsUri, 'ex:customField', 'value');
$personalNode->appendChild($exNode);
?>
$targetDom->importNode($node, true) 匯入。formatOutput=true 需配合 preserveWhiteSpace=false,且原 XML 不能有混合內容(元素夾雜文字)導致縮排異常。createTextNode() 或 createElement() 設定文字時,<>&" 會自動轉為實體,不要 自行 htmlentities() 重複編碼。<?php
$writer = new XMLWriter();
$writer->openMemory();
$writer->setIndent(true);
$writer->startDocument('1.0', 'UTF-8');
$writer->startElement('contacts');
// ... 迴圈寫入大量資料 ...
$writer->endElement();
$writer->endDocument();
file_put_contents('output.xml', $writer->outputMemory());
?>
掌握 DOMDocument 節點增刪改查,是處理 XML 設定檔、資料交換、RSS/Atom 產生、SVG 操作等場景的核心技能。