У меня есть код ниже, который разбирает XML-файл и извлекает дочернюю информацию на основе другого дочернего значения.
Код работает хорошо, но мой XML-файл имеет более 200 МБ, и когда я пытаюсь проанализировать и получить несколько данных, сайт загружается в течение 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, $ attribute)
Вторая функция, которая вызывается конечным элементом 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-> открытая (»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);
Других решений пока нет …