我有以下代码解析xml文件,根据另一个子值提取子信息。 代码运行良好,但我的xml文件超过200mb,当我尝试解析并获得几个数据时,网站加载大约4分钟或更长时间:(
$dom = new DOMDocument();
$xpath = new DOMXPath($dom);
$reader = new XMLReader();
$reader->open('http://www.bookingassist.ro/test/HotelsPro.xml');
while ($reader->read()) {
if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'Hotel') {
$node = $dom->importNode($reader->expand(), true);
$dom->appendChild($node);
$h1name = $xpath->evaluate('string(/Hotel[HotelCode = "'.$hotelCodes[0].'"]/HotelName)', $node);
$dom->removeChild($node);
if ($h1name) {
$reader->close();
break;
}
}
}
如何解析此文档以更快地检索数据。正如我在互联网上搜索SAX会做的事情,但我不知道如何使用它。 谢谢你的时间。
答案 0 :(得分:2)
DOM解析器将数据加载到内存中。 SAX解析器是一个流解析器,我发现它非常快速有效。
SAX解析器面临的挑战是,您需要知道标记名称并在流式传输XML时捕获数据。
您需要设置三个函数才能使用SAX解析器......
第一个由XML的开始元素(开始标记)触发的函数。此函数返回开始标记的名称和任何属性。
function startElement($ xml_parser,$ name,$ attributes)
由XML的结束元素(结束标记)触发的第二个函数。此函数仅返回结束标记的名称。
function endElement($ xml_parser,$ name)
最后,第三个函数处理在开始和结束元素(开始和结束标记)之间流式传输的字符数据。
function characterData($ xml_parser,$ data)
您需要将您的逻辑放入这三个功能中来完成工作,即时存储您需要的任何信息。当您使用不同的开始或结束标签时,请使用CASE功能执行不同的操作。
一旦掌握了功能,就可以初始化解析器...... 您必须使用 xml_set_element_handler 中的函数名称和 xml_set_character_data_handler 选项。
//Initialise SAX parser
$xml_parser = xml_parser_create("UTF-8"); //With UTF8 encoding
//Set parser options
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true); //This is a default setting of making all tags uppercase, if set to false you will get the tag name as it's set in the XML.
xml_parser_set_option($xml_parser, XML_OPTION_SKIP_WHITE, true); //This should skip values with no values
xml_parser_set_option($xml_parser, XML_OPTION_TARGET_ENCODING, "UTF-8"); //Set the output as UTF-8
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");
现在你可以打开流....
$ XML->打开(' http://www.bookingassist.ro/test/HotelsPro.xml&#39);
你解析数据。 将触发三个功能中的一个,具体取决于它是开始标记,结束标记还是字符数据。
while ($data = read($xml, 4096))
{
if (!xml_parse($xml_parser, $data, feof($xml))) {
echo "Error in the XML data\t" . xml_error_string(xml_get_error_code($xml_parser)));
break;
}
}
解析器完成后,使用....发布资源
xml_parser_free($xml_parser);