XML 표준에서 법적 XML 문서에는 하나의 루트 요소 (루트 요소) 만 있어야합니다. 그러나 실제 애플리케이션 시나리오에서는 여러 루트 요소가 포함 된 파일과 같은 "비표준"형식의 일부 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);