SAX(Simple API for XML)採用事件驅動:解析器逐行讀取 XML,遇到開始標籤、結束標籤、文字資料時觸發對應回調函數。開發者需在回調中維護狀態(如當前深度、父節點路徑)以重建結構。
<?php
$file = "data.xml";
$depth = [];
// 開始標籤回調
function startElement($parser, $name, $attrs) {
global $depth;
// 依深度縮排
for ($i = 0; $i < $depth[$parser]; $i++) {
print " ";
}
print "$name\n";
$depth[$parser]++;
}
// 結束標籤回調
function endElement($parser, $name) {
global $depth;
$depth[$parser]--;
}
// 1. 建立解析器
$xml_parser = xml_parser_create();
// 2. 註冊元素處理器
xml_set_element_handler($xml_parser, "startElement", "endElement");
// 3. 開啟檔案逐塊解析
if (!($fp = fopen($file, "r"))) {
die("could not open XML input");
}
while ($data = fread($fp, 4096)) {
if (!xml_parse($xml_parser, $data, feof($fp))) {
die(sprintf(
"XML error: %s at line %d",
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser)
));
}
}
// 4. 釋放資源
xml_parser_free($xml_parser);
?>
| 函數 | 用途 |
|---|---|
xml_parser_create() | 建立解析器資源 |
xml_set_element_handler() | 設定開始/結束標籤回調 |
xml_set_character_data_handler() | 設定文字資料回調(可選) |
xml_parse() | 解析資料塊,第三參數標示是否為最後一塊 |
xml_get_error_code() | 取得錯誤代碼 |
xml_error_string() | 錯誤代碼轉人類可讀訊息 |
xml_get_current_line_number() | 取得錯誤發生行號 |
xml_parser_free() | 釋放解析器記憶體 |
$depth[$parser] 追蹤巢狀深度;global、靜態變數或物件屬性(PHP 5+ 建議封裝為類)。適用: 大型 XML(>100MB)、串流處理、記憶體嚴格受限、僅需單次順序讀取。
不適合: 需隨機存取、修改 XML 結構、複雜 XPath 查詢、多次遍歷——請改用 DOMDocument 或 XMLReader。