Проверка большого XML-файла ~ 400 МБ в PHP

У меня есть большой XML-файл (около 400 МБ), который мне нужно, чтобы он был хорошо сформирован, прежде чем я начну его обрабатывать.

Первое, что я пробовал, было похоже на то, что было показано ниже, что здорово, поскольку я могу узнать, плохо ли сформирован XML и какие части XML являются «плохими»,

$doc = simplexml_load_string($xmlstr); if (!$doc) { $errors = libxml_get_errors(); foreach ($errors as $error) { echo display_xml_error($error); } libxml_clear_errors(); } 

Также попробовал …

 $doc->load( $tempFileName, LIBXML_DTDLOAD|LIBXML_DTDVALID ) 

Я тестировал это с файлом около 60 МБ, но все, что намного больше (~ 400 МБ), вызывает что-то новое для меня «убийца oom», чтобы запустить и завершить скрипт после того, что всегда кажется 30 секундами.

Я подумал, что мне, возможно, потребуется увеличить память на скрипте, поэтому выяснил пиковое использование при обработке 60 МБ и соответствующим образом скорректировал его для большого, а также отменил срок действия сценария на всякий случай.

 set_time_limit(0); ini_set('memory_limit', '512M'); 

К сожалению, это не сработало, поскольку убийца oom, похоже, является линексом, который срабатывает, если загрузка памяти (даже правильный термин?) Постоянно высока.

Было бы здорово, если бы я мог каким-то образом загрузить xml в кусках, поскольку, как я полагаю, это уменьшит нагрузку на память, так что убийца ома не будет вставлять свой жирный нос и убить мой процесс.

Кто-нибудь имеет опыт проверки большого файла XML и записи ошибок в том, где он плохо сформирован, много сообщений, которые я прочитал, указывают на SAX и XMLReader, которые могут решить мою проблему.

ОБНОВЛЕНИЕ Итак, @chiborg в значительной степени решила эту проблему для меня … Единственным недостатком этого метода является то, что я не вижу всех ошибок в файле, только первое, что не получилось, что я думаю, имеет смысл, поскольку я думаю он не может проанализировать прохождение первой точки, которая терпит неудачу.

При использовании simplexml … он способен фиксировать большинство проблем в файле и показывать мне в конце, что было хорошо.

Поскольку API SimpleXML и DOM всегда будут загружать документ в память, лучше использовать подход с использованием потокового анализатора, такого как SAX или XMLReader.

Адретируя код на странице примера , он может выглядеть так:

 $xml_parser = xml_parser_create(); if (!($fp = fopen($file, "r"))) { die("could not open XML input"); } while ($data = fread($fp, 4096)) { if (!xml_parse($xml_parser, $data, feof($fp))) { $errors[] = array( xml_error_string(xml_get_error_code($xml_parser)), xml_get_current_line_number($xml_parser)); } } xml_parser_free($xml_parser); 

Для большого файла идеальный класс XMLReader.

Но если используется синтаксис simplexml: https://github.com/dkrnl/SimpleXMLReader/blob/master/library/SimpleXMLReader.php Пример использования: http://github.com/dkrnl/SimpleXMLReader/blob/master/examples/example1. PHP