當前位置: 首頁> 最新文章列表> 如何通過xml_parse 解析多個根元素的XML 文件

如何通過xml_parse 解析多個根元素的XML 文件

M66 2025-04-28

在XML 標準中,一個合法的XML 文檔應該只能有一個根元素(Root Element)。但在實際應用場景中,有時候我們會遇到一些“非標準”格式的XML 文件,比如一個文件中包含多個根元素。這種結構在使用PHP 的xml_parse解析器時會引發問題,因為解析器默認是以標準XML 格式工作的。

那麼,如何才能正確解析這種包含多個根元素的XML 文件呢?本文將帶你一步步解決這個問題。

問題示例

設想我們有這樣一個XML 文件data.xml ,內容如下:

 <item>
  <name>Item 1</name>
</item>
<item>
  <name>Item 2</name>
</item>

在標準XML 中,這是不合法的,因為它包含了兩個頂級的<item>元素。

方法一:包裹為單一根節點

一種常見的解決方法是,在程序中人為地為這些內容添加一個“虛擬”的根節點。

 $xmlContent = file_get_contents('https://m66.net/data.xml');

// 包裹一個虛擬的根節點
$xmlContent = "<root>$xmlContent</root>";

$parser = xml_parser_create();
xml_parse_into_struct($parser, $xmlContent, $values, $index);
xml_parser_free($parser);

print_r($values);

這樣處理後, xml_parse就可以把整個文檔看作是一個合法的XML 文件來處理,解析過程也就不會報錯了。

方法二:逐行解析多個片段

如果XML 文件非常大,或者你不想一次性讀取所有內容,也可以使用xml_parse的流式處理方式,一段一段地解析。

 $parser = xml_parser_create();

function startElement($parser, $name, $attrs) {
    echo "Start: $name\n";
}

function endElement($parser, $name) {
    echo "End: $name\n";
}

function characterData($parser, $data) {
    echo "Data: " . trim($data) . "\n";
}

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

$handle = fopen("https://m66.net/data.xml", "r");
if ($handle) {
    // 包裹每個 <item> 塊,加上虛擬根元素進行逐段解析
    $chunk = '';
    while (($line = fgets($handle)) !== false) {
        $chunk .= $line;
        if (strpos($line, '</item>') !== false) {
            $xml = "<root>$chunk</root>";
            xml_parse($parser, $xml, true);
            $chunk = '';
        }
    }
    fclose($handle);
}

xml_parser_free($parser);