2014-12-18 3 views
1

У меня есть код ниже, в котором синтаксический анализ файла xml извлекает дочернюю информацию на основе другого дочернего значения. код работает хорошо, но мой файл XML имеет более 200mb, и когда я пытаюсь разобрать и получить несколько data`s сайт загружается примерно за 4 мин или более :(Разбор большого XML-файла с SAX & XPATH

$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

Этот пример не SAX, он использует XMLReader и DOM - различные интерфейсы – ThW

ответ

2

Парсер DOM загружает данные в память . SAX-парсер - это анализатор потока, который я нашел очень быстрым и эффективным.

Задача с SAX par ser заключается в том, что вам необходимо знать имена тегов и собирать данные по мере потока через XML.

Вам нужно настроить три функции использовать SAX-анализатор ...

  1. Первая функция, которая запускается при запуске элемента XML (открывающий тег). Эта функция возвращает имя открытого тега и любых атрибутов.

    функция StartElement ($ XML_Parser, $ имя, $ атрибуты)

  2. Вторая функция, которая запускается конечным элементом XML (закрывающий тег). В этой функции возвращается только имя закрывающего тега.

    функция EndElement ($ XML_Parser, $ название)

  3. Наконец, третья функция для обработки данных символа, который потокового между начальным и конечным элементами (открытие и закрытие тегов).

    функция CharacterData ($ XML_Parser, $ данных)

Вам нужно будет поставить свою логику в этих трех функций, чтобы сделать работу, хранить любую необходимую вам информацию на лету. Используйте функцию 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); 
Смежные вопросы