當前位置: 首頁> 最新文章列表> 如何在xml_parse 中使用遞歸解析嵌套XML 文檔

如何在xml_parse 中使用遞歸解析嵌套XML 文檔

M66 2025-05-12

在PHP 中處理XML 文檔時, xml_parse()是一個低層級但強大的函數。它依賴事件驅動的解析模型,因此你需要註冊相應的回調函數來響應文檔的開始、結束以及字符數據。

然而,面對嵌套結構複雜的XML 文檔,使用遞歸可以讓數據處理變得更直觀且結構清晰。本文將介紹如何結合遞歸與xml_parse()來解析嵌套的XML 數據。

一、示例XML 數據

<catalog>
    <book id="1">
        <title>PHP Basics</title>
        <author>John Doe</author>
    </book>
    <book id="2">
        <title>Advanced PHP</title>
        <author>Jane Smith</author>
    </book>
</catalog>

二、創建解析器並設置處理函數

我們首先需要創建一個解析器,並設置三種回調函數:

  • startElement() :當解析器遇到一個開始標籤時調用;

  • endElement() :當解析器遇到一個結束標籤時調用;

  • characterData() :當解析器遇到標籤中的文本時調用。

三、實現遞歸結構的關鍵:構建樹狀數組

下面是完整代碼示例:

 <?php

$xml = <<<XML
<catalog>
    <book id="1">
        <title>PHP Basics</title>
        <author>John Doe</author>
    </book>
    <book id="2">
        <title>Advanced PHP</title>
        <author>Jane Smith</author>
    </book>
</catalog>
XML;

$parser = xml_parser_create();
$dataStack = [];
$currentData = null;

// 開始標籤
function startElement($parser, $name, $attrs) {
    global $dataStack, $currentData;

    $element = [
        'tag' => $name,
        'attributes' => $attrs,
        'children' => [],
        'value' => ''
    ];

    if ($currentData !== null) {
        array_push($dataStack, $currentData);
    }

    $currentData = $element;
}

// 結束標籤
function endElement($parser, $name) {
    global $dataStack, $currentData;

    if (!empty($dataStack)) {
        $parent = array_pop($dataStack);
        $parent['children'][] = $currentData;
        $currentData = $parent;
    }
}

// 文本內容
function characterData($parser, $data) {
    global $currentData;

    if (isset($currentData['value'])) {
        $currentData['value'] .= trim($data);
    }
}

xml_set_element_handler($parser, "startElement", "endElement");
xml_set_character_data_handler($parser, "characterData");

if (!xml_parse($parser, $xml, true)) {
    die(sprintf("XML 錯誤: %s 在第 %d 行",
        xml_error_string(xml_get_error_code($parser)),
        xml_get_current_line_number($parser)));
}

xml_parser_free($parser);

// 打印最終結構
print_r($currentData);
?>

四、輸出結構說明

解析後,你將得到一個嵌套的數組結構,類似以下內容:

 Array
(
    [tag] => CATALOG
    [attributes] => Array()
    [children] => Array
        (
            [0] => Array
                (
                    [tag] => BOOK
                    [attributes] => Array ( [ID] => 1 )
                    [children] => Array
                        (
                            [0] => Array ( [tag] => TITLE [value] => PHP Basics )
                            [1] => Array ( [tag] => AUTHOR [value] => John Doe )
                        )
                )
            [1] => Array
                (
                    [tag] => BOOK
                    [attributes] => Array ( [ID] => 2 )
                    [children] => Array
                        (
                            [0] => Array ( [tag] => TITLE [value] => Advanced PHP )
                            [1] => Array ( [tag] => AUTHOR [value] => Jane Smith )
                        )
                )
        )
)

五、將解析結構轉換為JSON 或其他格式

你可以輕鬆地將上面的數組結構轉換為JSON,以供前端調用或接口輸出:

 echo json_encode($currentData, JSON_PRETTY_PRINT);

六、小貼士

  • 如果XML 文檔來源於網絡,比如https://m66.net/data/books.xml ,你可以使用file_get_contents()獲取: