現在の位置: ホーム> 最新記事一覧> XML_PARSEでネストされたXMLドキュメントを再帰的に解析する方法

XML_PARSEでネストされたXMLドキュメントを再帰的に解析する方法

M66 2025-05-12

PHPでXMLドキュメントを操作する場合、 XML_PARSE()は低レベルだが強力な機能です。イベント駆動型の解析モデルに依存するため、ドキュメントデータの最初、終了、および文字データの最初、終わりに応答するために、対応するコールバック関数を登録する必要があります。

ただし、複雑な構造を持つネストされたXMLドキュメントに直面して、再帰を使用すると、データ処理がより直感的かつ明確になる可能性があります。この記事では、再帰およびXML_PARSE()と組み合わせてネストされたXMLデータを解析する方法を紹介します。

1。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>

2。パーサーを作成し、処理機能をセットアップします

最初にパーサーを作成し、3つのコールバック関数を設定する必要があります。

  • startelement() :パーサーが開始タグに遭遇したときに呼び出されます。

  • endelement() :パーサーがエンドタグに遭遇したときに呼び出されます。

  • CharpleDATA() :パーサーがタグ内のテキストに遭遇したときに呼び出されます。

3。再帰構造を実装するための鍵:木のような配列の構築

これが完全なコードの例です。

 <?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);
?>

4。出力構造の説明

解析後、以下と同様のネストされた配列構造が得られます。

 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 )
                        )
                )
        )
)

5。解析された構造をJSONまたはその他の形式に変換します

上記の通話またはインターフェイス出力のために、上記の配列構造をJSONに簡単に変換できます。

 echo json_encode($currentData, JSON_PRETTY_PRINT);

六。ヒント

  • XMLドキュメントがhttps://m66.net/data/books.xmlなどのネットワークから来ている場合、 file_get_contents()を使用して取得できます。