PHPでXMLドキュメントを操作する場合、 XML_PARSE()は低レベルだが強力な機能です。イベント駆動型の解析モデルに依存するため、ドキュメントデータの最初、終了、および文字データの最初、終わりに応答するために、対応するコールバック関数を登録する必要があります。
ただし、複雑な構造を持つネストされたXMLドキュメントに直面して、再帰を使用すると、データ処理がより直感的かつ明確になる可能性があります。この記事では、再帰およびXML_PARSE()と組み合わせてネストされた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>
最初にパーサーを作成し、3つのコールバック関数を設定する必要があります。
startelement() :パーサーが開始タグに遭遇したときに呼び出されます。
endelement() :パーサーがエンドタグに遭遇したときに呼び出されます。
CharpleDATA() :パーサーがタグ内のテキストに遭遇したときに呼び出されます。
これが完全なコードの例です。
<?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に簡単に変換できます。
echo json_encode($currentData, JSON_PRETTY_PRINT);
XMLドキュメントがhttps://m66.net/data/books.xmlなどのネットワークから来ている場合、 file_get_contents()を使用して取得できます。