XML(eXtensible Markup Language)是 W3C 標準,設計目標是「傳輸與存儲數據」,而非顯示數據。其標簽自定義、結構嚴謹、跨平台特性使其成為異構系統數據交換的通用格式。常見應用場景:XHTML、XML-RPC、RSS、AJAX、配置文件、Web Services(SOAP/REST)。
<?xml version="1.0"?>
<library>
<categories>
<category cid="1">Web Development</category>
<category cid="2">Database Programming</category>
<category cid="3">PHP</category>
<category cid="4">Java</category>
</categories>
<books>
<book>
<title>Apache 2</title>
<author>Peter Wainwright</author>
<publisher>Wrox</publisher>
<category>1</category>
</book>
<book>
<title>Advanced PHP Programming</title>
<author>George Schlossnagle</author>
<publisher>Developer Library</publisher>
<category>1</category>
<category>3</category>
</book>
<book>
<title>Visual FoxPro 6 - Programmers Guide</title>
<author>Eric Stroo</author>
<publisher>Microsoft Press</publisher>
<category>2</category>
</book>
<book>
<title>Mastering Java 2</title>
<author>John Zukowski</author>
<publisher>Sybex</publisher>
<category>4</category>
</book>
</books>
</library>
適用於需頻繁修改結構(增刪節點、屬性)、大文檔流式處理、跨語言移植(JS/Java/Python DOM API 一致)。
<?php
$dom = new DOMDocument('1.0');
$dom->load('xml/library.xml');
// 建立分類 ID -> 名稱映射
$categories = [];
$catNodes = $dom->getElementsByTagName('categories')->item(0)
->getElementsByTagName('category');
foreach ($catNodes as $node) {
$cid = $node->getAttribute('cid');
$categories[$cid] = $node->nodeValue; // nodeValue 等同 firstChild->nodeValue
}
// 輸出圖書信息
foreach ($dom->getElementsByTagName('book') as $book) {
$title = $book->getElementsByTagName('title')->item(0)->nodeValue;
$author = $book->getElementsByTagName('author')->item(0)->nodeValue;
$catList = [];
foreach ($book->getElementsByTagName('category') as $cat) {
$catList[] = $categories[$cat->nodeValue];
}
echo "<div><h2>$title</h2>";
echo "<p><b>Author:</b> $author</p>";
echo "<p><b>Categories:</b> " . implode('、', $catList) . "</p></div>";
}
?>
function addCategory(DOMDocument $dom, $cid, $name) {
$catNode = $dom->createElement('category');
$catNode->setAttribute('cid', $cid);
$catNode->appendChild($dom->createTextNode($name));
$categories = $dom->getElementsByTagName('categories')->item(0);
$categories->appendChild($catNode);
}
// 使用
addCategory($dom, 5, 'Go Language');
$dom->save('xml/library.xml'); // 持久化
$dom->save('file.xml'):直接寫入文件$dom->saveXML($node):返回節點或整棵樹的 XML 字符串將 XML 映射為對象/數組混合結構,屬性用 ['attr'] 訪問,元素用 ->element 或 ->element[0] 訪問,文本需 (string) 強制轉換。
<?php
$xml = simplexml_load_file('xml/library.xml');
// 分類映射
$categories = [];
foreach ($xml->categories->category as $cat) {
$categories[(string)$cat['cid']] = (string)$cat;
}
// 輸出圖書
foreach ($xml->books->book as $book) {
$catList = [];
foreach ($book->category as $cat) {
$catList[] = $categories[(string)$cat];
}
echo "<div><h2>{$book->title}</h2>";
echo "<p><b>Author:</b> {$book->author}</p>";
echo "<p><b>Categories:</b> " . implode('、', $catList) . "</p></div>";
}
?>
function addCategory(SimpleXMLElement &$sxml, $cid, $name) {
$dom = new DOMDocument();
$dom->loadXML($sxml->asXML()); // SimpleXML -> DOM
$cat = $dom->createElement('category');
$cat->setAttribute('cid', $cid);
$cat->appendChild($dom->createTextNode($name));
$dom->getElementsByTagName('categories')->item(0)->appendChild($cat);
$sxml = simplexml_import_dom($dom); // DOM -> SimpleXML
return $sxml;
}
SimpleXML 與 DOM 均內建 XPath 支援。常用路徑語法:
| XPath 表達式 | 含義 |
|---|---|
//category | 文檔中所有 category 元素 |
/library/books | 根節點下的 books 子元素 |
/library/categories/category[@cid] | 帶 cid 屬性的 category |
/library/categories/category[@cid='2'] | cid=2 的 category |
/library/books/book[title='Apache 2'] | 標題為 Apache 2 的 book |
<?php
$xml = simplexml_load_file('xml/library.xml');
foreach ($xml->xpath("/library/books/book") as $book) {
$catList = [];
foreach ($book->category as $catId) {
// 反向查找分類名
$cat = $xml->xpath("/library/categories/category[@cid='$catId']");
$catList[] = (string)$cat[0];
}
// 輸出...
}
?>
$xpath = new DOMXPath($dom);
$books = $xpath->evaluate("/library/books/book[title='Apache 2']");
foreach ($books as $book) {
// $book 是 DOMElement
}
| 維度 | DOM | SimpleXML | XPath |
|---|---|---|---|
| 學習曲線 | 較陡(冗長 API) | 平緩(直觀屬性訪問) | 中等(需學路徑語法) |
| 內存佔用 | 高(整棵樹載入) | 高(同 DOM) | 依賴宿主解析器 |
| 修改能力 | 完整(增刪改查) | 受限(需轉 DOM) | 唯讀查詢 |
| 查詢靈活性 | 需手動遍歷 | 需手動遍歷 | 極強(複雜條件一行搞定) |
| 推薦場景 | 需修改結構、大文檔、跨語言 | 純讀取、結構固定、快速開發 | 複雜條件篩選、報表統計 |
simplexml_load_file() + XPath 精準提取DOMDocument 構建樹 → save() 持久化XMLReader(拉式解析)+ XMLWriter,避免全量載入內存DOMXPath::registerNamespace() 或 SimpleXMLElement::registerXPathNamespace()PHP 5+ 提供了成熟的 XML 工具鏈:DOM 兼容標準、SimpleXML 開發高效、XPath 查詢強大。實際項目中常「SimpleXML 讀取 + XPath 篩選 + DOM 修改」組合使用。掌握三者優缺點,可根據業務場景靈活選型,避免過度設計或性能瓶頸。