我有下面的代码,它正在解析 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 可以做到这一点,但我不知道如何使用它。 感谢您抽出时间。
最佳答案
DOM 解析器将数据加载到内存中。 SAX 解析器是一个流解析器,我发现它非常快速且高效。
SAX 解析器面临的挑战是您需要知道标签名称并在通过 XML 流式传输时捕获数据。
您需要设置三个函数才能使用 SAX 解析器...
第一个函数由 XML 的开始元素(开始标记)触发。此函数返回开始标记的名称和所有属性。
函数startElement($xml_parser, $name, $attributes)
第二个函数由 XML 的结束元素(结束标记)触发。此函数仅返回结束标记的名称。
函数 endElement($xml_parser, $name)
最后,第三个函数处理在开始和结束元素(开始和结束标记)之间流式传输的字符数据。
函数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->open('http://www.bookingassist.ro/test/HotelsPro.xml');
然后您解析数据。 根据是开始标记、结束标记还是字符数据,将触发这三个函数之一。
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);
关于php - 使用 SAX 和 XPATH 解析大型 XML 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27542104/