處理 XML 資料結構是後端開發常見需求。PHP 內建 DOMDocument 類提供強大、標準化的 API,能程式化建立、操作並輸出符合標準的 XML 文件。本文將由淺入深示範完整流程。
<?php
$dom = new DOMDocument("1.0"); // 版本 1.0
header("Content-Type: text/plain"); // 方便瀏覽器查看原始碼
echo $dom->saveXML();
// 輸出:<?xml version="1.0"?>
?>
核心兩步驟:
1. createElement() / createTextNode() 建立節點物件。
2. appendChild() 掛載至父節點,構建樹狀結構。
<?php
$dom = new DOMDocument("1.0");
header("Content-Type: text/plain");
// 建立根元素 <toppings>
$root = $dom->createElement("toppings");
$dom->appendChild($root);
// 建立子元素 <item> 並掛載到根節點
$item = $dom->createElement("item");
$root->appendChild($item);
// 建立文字節點並掛載到 <item>
$text = $dom->createTextNode("pepperoni");
$item->appendChild($text);
echo $dom->saveXML();
// 輸出:
// <?xml version="1.0"?>
// <toppings><item>pepperoni</item></toppings>
?>
重複建立 item 並 appendChild 到同一個 root 即可。
$item2 = $dom->createElement("item");
$root->appendChild($item2);
$text2 = $dom->createTextNode("tomato");
$item2->appendChild($text2);
// 輸出會包含兩個 <item> 節點
屬性也是節點,需先 createAttribute() 建立屬性節點,再建立文字節點作為屬性值,最後掛載至元素。
$price = $dom->createAttribute("price");
$item->appendChild($price);
$priceValue = $dom->createTextNode("4");
$price->appendChild($priceValue);
// 結果:<item price="4">pepperoni</item>
createCDATASection():包含特殊字元、不需轉義的資料區塊。createProcessingInstruction():給 XML 解析器的指令(如樣式表關聯)。$cdata = $dom->createCDATASection("Customer requests pizza sliced into 16 square pieces");
$root->appendChild($cdata);
$pi = $dom->createProcessingInstruction("pizza", "bake()");
$root->appendChild($pi);
// 輸出包含:<![CDATA[...]]> 和 <?pizza bake()?>
save('filename.xml'):直接寫入檔案,可搭配 $dom->formatOutput = true; 美化縮排。saveXML():回傳 XML 字串,存入變數或直接輸出。$dom->formatOutput = true; // 開啟美化格式
$dom->save("order.xml"); // 存檔
$xmlString = $dom->saveXML(); // 存變數
<?php
$conn = mysql_connect('localhost', 'root', '123456') or die('Connect failed: ' . mysql_error());
mysql_select_db('vdigital', $conn) or die('DB select failed: ' . mysql_error());
$sql = "SELECT id, username FROM `admin` GROUP BY `id` ORDER BY `id` ASC";
$result = mysql_query($sql) or die('Query failed: ' . mysql_error());
$xmlDoc = new DOMDocument();
$xmlFile = "01.xml";
if ($result) {
// 若檔案不存在,建立基本結構
if (!file_exists($xmlFile)) {
$xmlStr = "<?xml version='1.0' encoding='utf-8' ?><message></message>";
$xmlDoc->loadXML($xmlStr);
$xmlDoc->save($xmlFile);
} else {
$xmlDoc->load($xmlFile);
}
$root = $xmlDoc->documentElement;
while ($row = mysql_fetch_array($result)) {
// 建立 <id> 節點
$nodeId = $xmlDoc->createElement("id");
$nodeId->appendChild($xmlDoc->createTextNode(iconv("GB2312", "UTF-8", $row["id"])));
$root->appendChild($nodeId);
// 建立 <name> 節點
$nodeName = $xmlDoc->createElement("name");
$nodeName->appendChild($xmlDoc->createTextNode(iconv("GB2312", "UTF-8", $row["username"])));
$root->appendChild($nodeName);
$xmlDoc->save($xmlFile); // 每次迴圈存檔,或迴圈結束後存一次
}
}
mysql_close($conn);
?>
<?php
$xmlDoc = new DOMDocument();
$xmlDoc->load("https://localhost/xml/xml.php"); // 或本地檔案
$names = $xmlDoc->getElementsByTagName('name');
for ($i = 0; $i < $names->length; $i++) {
if (strpos($names->item($i)->nodeValue, "fang") !== false) {
// 取得同層前一個節點 (id) 的值
echo $names->item($i)->parentNode->childNodes->item(1)->nodeValue;
}
}
?>
DOMDocument 雖然程式碼較冗長,但結構清晰、符合 W3C 標準、支援命名空間、XPath、Schema 驗證等進階功能,是 PHP 處理複雜 XML 的首選工具。掌握「建立節點 → 掛載樹狀結構 → 輸出/儲存」核心流程,即可應對大多數生成需求。