| 模型 | 特性 | 適用場景 | 記憶體 |
|---|---|---|---|
| DOM (Document Object Model) | 樹狀結構完整載入記憶體,支援完整 CRUD、XPath、XSLT | 中小型 XML、需修改結構、XSLT 轉換 | 高 (整份文件) |
| SimpleXML | 物件導向 API,屬性/子元素如屬性存取,支援 XPath | 讀取導向、結構固定、開發效率優先 | 高 (整份文件) |
| XMLReader (Pull Parser) | 流式讀取,游標前進,不載入整份文件 | 大型 XML (GB 級)、記憶體受限、單向讀取 | 極低 (串流) |
<?php
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<book id="bk101">
<title>XML Developer's Guide</title>
<author>Gambardella, Matthew</author>
<price>44.95</price>
</book>
</catalog>
XML;
$dom = new DOMDocument();
$dom->loadXML($xml);
$dom->formatOutput = true; // 美化輸出
// XPath 查詢
$xpath = new DOMXPath($dom);
$books = $xpath->query('//book[@id="bk101"]');
foreach ($books as $book) {
echo "Title: " . $xpath->evaluate('string(title)', $book) . "\n";
// 修改
$price = $xpath->query('price', $book)->item(0);
$price->textContent = '49.95';
// 新增屬性
$book->setAttribute('updated', 'true');
}
echo $dom->saveXML();
// 載入/儲存檔案
// $dom->load('large.xml');
// $dom->save('output.xml');
?>
<?php
$xml = simplexml_load_string($xmlString); // 或 simplexml_load_file('file.xml')
// 存取如物件屬性
echo $xml->book[0]->title . "\n";
// 迭代
foreach ($xml->book as $book) {
echo (string)$book->title . ' - ' . (string)$book->price . "\n";
}
// XPath
$results = $xml->xpath('//book[price > 40]');
// 命名空間
$xml->registerXPathNamespace('ns', 'https://example.com/ns');
$nsResults = $xml->xpath('//ns:item');
// 轉 DOM 進行複雜操作
$dom = dom_import_simplexml($xml)->ownerDocument;
?>
<?php
$reader = new XMLReader();
$reader->open('huge.xml'); // 或 XML($string)
while ($reader->read()) {
if ($reader->nodeType === XMLReader::ELEMENT && $reader->localName === 'book') {
// 擴展為 SimpleXML 節點處理 (僅該節點樹)
$node = simplexml_import_dom($reader->expand());
$id = (string)$node['id'];
$title = (string)$node->title;
// 處理單筆...
if ($id === 'bk101') {
echo "Found: $title\n";
break; // 可提前結束
}
}
}
$reader->close();
?>
<?php
$dom = new DOMDocument();
$dom->load('data.xml');
if (!$dom->schemaValidate('schema.xsd')) {
foreach (libxml_get_errors() as $error) {
error_log("XML 驗證錯誤: {$error->message} at line {$error->line}");
}
libxml_clear_errors();
}
?>
安全**:防 XXE 攻擊:libxml_disable_entity_loader(true) (PHP 8.0+ 預設關閉外部實體)。
注意:現代專案建議改用 REST/JSON 或 gRPC。XML-RPC 僅用於維護舊系統整合。
<?php
function sample_add($method, $params) {
return $params[0] + $params[1];
}
$server = xmlrpc_server_create();
xmlrpc_server_register_method($server, 'sample.add', 'sample_add');
$request = file_get_contents('php://input');
$response = xmlrpc_server_call_method($server, $request, null);
header('Content-Type: text/xml');
echo $response;
xmlrpc_server_destroy($server);
?>
<?php
$request = xmlrpc_encode_request('sample.add', [5, 3]);
$ctx = stream_context_create(['http' => [
'method' => 'POST',
'header' => 'Content-Type: text/xml',
'content' => $request,
]]);
$response = file_get_contents('https://localhost/xmlrpc_server.php', false, $ctx);
$result = xmlrpc_decode($response);
echo "5 + 3 = $result\n"; // 8
?>
XMLWriter (流式寫入,低記憶體)。