根據文件大小、記憶體限制、查詢靈活度選擇合適解析器。本文以統一範例數據演示三種方式代碼與優缺點。
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="children">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="web" cover="paperback">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
$dom = new DOMDocument();
$dom->load('books.xml');
$books = $dom->getElementsByTagName('book');
foreach ($books as $book) {
$title = $book->getElementsByTagName('title')->item(0)->textContent;
$author = $book->getElementsByTagName('author')->item(0)->textContent;
$year = $book->getElementsByTagName('year')->item(0)->textContent;
$price = $book->getElementsByTagName('price')->item(0)->textContent;
echo "$title | $author | $year | $$price\n";
}
// 支援 XPath 查詢
$xpath = new DOMXPath($dom);
$webBooks = $xpath->query('//book[@category="web"]');
優點:完整樹結構、支援 XPath、可修改寫回。缺點:整文檔載入記憶體,大文件 (>50MB) 易 OOM。
$parser = xml_parser_create();
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
xml_set_element_handler($parser, 'startElement', 'endElement');
xml_set_character_data_handler($parser, 'charData');
$fp = fopen('books.xml', 'r');
while ($data = fread($fp, 4096)) {
xml_parse($parser, $data, feof($fp));
}
fclose($fp);
xml_parser_free($parser);
// 回調函數需自行維護狀態機
function startElement($parser, $name, $attrs) { /* 入棧 $name, $attrs */ }
function endElement($parser, $name) { /* 出棧 */ }
function charData($parser, $data) { /* 累加文本 */ }
優點:流式讀取、記憶體恆定、適合超大文件 (GB 級)。缺點:代碼冗長、需手寫狀態機、無法隨機訪問。
$xml = simplexml_load_file('books.xml');
foreach ($xml->book as $book) {
echo "{$book->title} | {$book->author} | {$book->year} | \${$book->price}\n";
// 屬性訪問
echo "Category: {$book['category']}\n";
echo "Lang: {$book->title['lang']}\n";
}
// XPath 支援
$results = $xml->xpath('//book[@category="web"]');
優點:語法極簡、屬性/節點統一為對象屬性、支援 XPath。缺點:大文件同樣載入全部內存、命名空間處理較繁瑣。
| 場景 | 推薦 | 理由 |
|---|---|---|
| 小文件 (<5MB)、需修改/複雜查詢 | DOMDocument | 功能最全、XPath 強大 |
| 小文件、唯讀、快速開發 | SimpleXML | 代碼最少、可讀性最高 |
| 大文件 (>50MB)、記憶體受限 | XML Parser (SAX) | 流式解析、恆定記憶體 |
| 超大文件 (GB)、需邊讀邊入庫 | XMLReader (Pull 模式) | 游標前進、隨時停止、PHP 5.1+ 內建 |
$reader = new XMLReader();
$reader->open('books.xml');
while ($reader->read()) {
if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'book') {
$node = simplexml_import_dom($reader->expand());
echo "{$node->title}\n";
}
}
$reader->close();