HTML 專注於展示,擴展性差、鏈接易斷、數據搜索困難、多語言支持弱。XML(可擴展標記語言)以「內容與展示分離」、「自定義標記」、「強大的鏈接機制 (XLink/XPointer/XPath)」、「Schema 驗證」、「命名空間隔離」等特性,成為數據交換、配置存儲、文檔發布的標準格式。PHP 提供豐富的 XML 解析擴展(SAX、DOM、SimpleXML、XMLReader),是處理 XML 的理想語言。
| 技術 | 作用 | 關鍵點 |
|---|---|---|
| DTD | 文檔類型定義 | 定義元素、屬性、實體;非 XML 語法,擴展性弱 |
| XML Schema (XSD) | 結構與數據類型驗證 | XML 語法、支持豐富數據類型、命名空間、可擴展 |
| XPath | 節點定位語言 | 路徑表達式選擇節點集,XSLT、XPointer 基礎 |
| XSLT | XML 轉換語言 | XML→HTML/XML/文本,模板匹配、模式規則 |
| XLink / XPointer | 高級鏈接 | 多向、標註、片段定位,超越 HTML 超鏈接 |
| DOM | 文檔對象模型 | 樹形內存模型,隨機訪問修改,跨語言標準 API |
| SAX | 事件驅動解析 | 流式、低內存、單向、適合大文件 |
| Namespaces | 命名空間 | URI 標識,避免元素名衝突,實現詞彙混合 |
| 擴展 | 模式 | 內存 | 速度 | 適用場景 | 學習曲線 |
|---|---|---|---|---|---|
| XMLParser (SAX) | 事件驅動 | 極低 | 快 | 大文件、流式處理、內存受限 | 中 |
| DOMDocument | 樹模型 | 高 (整文檔載入) | 中 | 需隨機訪問/修改、XSLT 轉換、文檔較小 | 低 (標準 API) |
| SimpleXML | 樹模型 (簡化) | 中 | 快 | 讀取簡單 XML、配置文件、RSS/Atom 解析 | 極低 |
| XMLReader | 拉式流式 | 極低 | 快 | 大文件、順序讀取、需 XPath 時配合 DOM | 中 |
$parser = xml_parser_create('UTF-8'); // 創建解析器
xml_set_element_handler($parser, 'startEl', 'endEl'); // 設置元素開始/結束回調
xml_set_character_data_handler($parser, 'charData'); // 設置字符數據回調
xml_parse($parser, $data, $isFinal); // 解析數據塊
xml_parser_free($parser); // 釋放資源
// 回調函數簽名
function startEl($parser, $name, $attrs) { /* $attrs 為屬性關聯數組 */ }
function endEl($parser, $name) { /* ... */ }
function charData($parser, $data) { /* 文本內容,可能分多次調用 */ }
<?xml version="1.0" encoding="UTF-8"?>
<addressbook>
<contact id="1">
<name>張三</name>
<phone type="mobile">13800001111</phone>
<email>zhangsan@example.com</email>
</contact>
<contact id="2">
<name>李四</name>
<phone type="home">010-88888888</phone>
</contact>
</addressbook>
<?php
$depth = []; // 記錄各解析器當前深度
function startElement($parser, $name, $attrs) {
global $depth;
$depth[$parser] = ($depth[$parser] ?? 0) + 1;
$indent = str_repeat('→', $depth[$parser] - 1);
$color = ['red', 'green', 'blue'][$depth[$parser] % 3];
$size = max(2, 5 - $depth[$parser]);
echo "<font size='$size' color='$color'>$indent$name</font><br>";
if ($attrs) {
foreach ($attrs as $k => $v) {
echo "<font size='$size' color='gray'>$indent @$k='$v'</font><br>";
}
}
}
function endElement($parser, $name) {
global $depth;
$depth[$parser]--;
}
function characterData($parser, $data) {
$data = trim($data);
if ($data !== '') {
global $depth;
$indent = str_repeat('→', $depth[$parser]);
echo "<font size='2' color='black'>$indent # $data</font><br>";
}
}
$parser = xml_parser_create('UTF-8');
xml_set_element_handler($parser, 'startElement', 'endElement');
xml_set_character_data_handler($parser, 'characterData');
$fp = fopen('address.xml', 'r');
while ($chunk = fread($fp, 4096)) {
if (!xml_parse($parser, $chunk, feof($fp))) {
die(sprintf("XML錯誤: %s at line %d",
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)));
}
}
fclose($fp);
xml_parser_free($parser);
?>
<?php
$xml = simplexml_load_file('address.xml');
foreach ($xml->contact as $contact) {
echo "<b>聯繫人 ID: {$contact['id']}</b><br>";
echo "姓名: {$contact->name}<br>";
foreach ($contact->phone as $phone) {
echo "電話 ({$phone['type']}): $phone<br>";
}
echo "郵箱: {$contact->email}<br><hr>";
}
?>
expand() 獲取 DOM 節點處理複雜片段。DOMXPath 查詢,importNode 移動節點,saveXML() 輸出。libxml_disable_entity_loader(true) (PHP 8.0+ 默認禁用),解析外部 XML 必開啟。$dom->schemaValidate('schema.xsd') 驗證。XML 雖不再是 API 主流格式(JSON 佔優),但在企業級集成、辦公文檔、出版流程、金融報文等領域不可替代。PHP 提供完整的 XML 工具鏈,掌握 SAX/DOM/SimpleXML/XMLReader 四大解析器的選型與使用,是後端工程師的核心基本功。