PHP – ошибка синтаксического анализа SimpleXML

ПОСМОТРЕТЬ РЕДАКТИКИ НА НИЖНЕМ ПОКАЗАТЬ БОЛЬШЕ ТОЧНОГО ОШИБКА ВЫХОДА

Я разбираю несколько больших (~ 15 МБ) XML-файлов с PHP в первый раз с помощью SimpleXML. Файлы – это результаты поиска в полете, поэтому у них есть длинные атрибуты (ссылки на байдарку, например:
"/book/flightcode=1238917408.NxJI6G.0.F.ORBITZAIR,ORBITZAIR.0.f36f1ea92513977249aa695112410052& sid = 26-Vu01v7ilzhSAjPVLZ3Ul"

SimpleXML выдает эту ошибку при разборе:

"Entity: строка 10: ошибка парсера: EntityRef: ожидается ';' в ", а затем;

«38917408.NxJI6G.0.F.ORBITZAIR, ORBITZAIR.0.f36f1ea92513977249aa695112410052 & sid in», а затем;

"simplexml_load_string () [function.simplexml-load-string]: ^ in,"

и т. д. для каждой строки, где есть эти URL-адреса.

Я нашел упоминание SimpleXML, не любившего длинные атрибуты на php.net без решения. Я бы предпочел просто использовать и изучать SimpleXML и работать над этой ошибкой, если есть нехорошее, несколько легкое обходное решение.

у кого-нибудь есть решение? Заранее спасибо!

Я попытался ввести первые 13 строк XML, но он выводит информацию без XML, поэтому я могу это сделать, если это поможет. Я не уверен, что использование другого парсера / расширения уменьшит функциональность или простоту использования, но, пожалуйста, не стесняйтесь предлагать другое, если нет обходного пути (DOM или XMLReader – это то, о чем я думаю, возможно).

ИЗМЕНИТЬ НИЖЕ, ЧТОБЫ ВКЛЮЧАТЬ МЕНЬШЕ ВРЕМЯ ВЫПОЛНЕННОГО ОШИБКА:

http://dl.dropbox.com/u/10206237/stack_overflow_xml.xml

ОШИБКА 1:

simplexml_load_string() [<a href='function.simplexml-load-string'>function.simplexml-load-string</a>]: Entity: line 10: parser error : EntityRef: expecting ';' in 

ОШИБКА 2: (Я думаю, что это хорошо, потому что он работает с скриптом Python с использованием DOM, я переводил его на PHP, потому что я не знаю Python). Я не знал, что вывод в браузере будет другим. Спасибо, что терпеливы.)

 <a href='function.simplexml-load-string'>function.simplexml-load-string</a>]: 38917408.Pt8rW8.0.F.ORBITZAIR,ORBITZAIR.0.f36f1ea92513977249aa695112410052&amp;_sid_ in 

ОШИБКА 3:

 function.simplexml-load-string</a>]: ^ in 

(все эти пространства там)

Как упоминалось в других ответах и ​​комментариях, ваш исходный XML не работает, и XML-парсеры должны отклонять недопустимый ввод. libxml имеет режим «восстановления», который позволит вам загрузить этот сломанный XML, но вы потеряете часть «& sid», чтобы это не помогло.

Если вам повезло, и вам нравится рисковать, вы можете попытаться каким-то образом заставить его работать, как бы фиксируя ввод. Вы можете использовать некоторую замену строк, чтобы избежать амперсандов, которые выглядят так, как будто они находятся в части запроса URL-адреса.

 $xml = file_get_contents('broken.xml'); // replace '&' followed by a bunch of letters, numbers // and underscores and an equal sign with &amp; $xml = preg_replace('#&(?=[a-z_0-9]+=)#', '&amp;', $xml); $sxe = simplexml_load_string($xml); 

Это, конечно, ничего, кроме взлома, и единственный хороший способ исправить вашу ситуацию – попросить вашего поставщика XML исправить свой генератор. Потому что, если он генерирует разбитый XML, кто знает, какие другие ошибки проскальзывают незаметно?

У Даррила есть правильный ответ, почему это происходит в его комментарии выше. Одним из способов его устранения было бы сделать str_replace (), чтобы заменить все «&» амперсанды на «& amp;» в XML. В соответствии с руководством PHP вы также можете использовать это регулярное выражение для замены амперсандов своими объектами:

 $s = preg_replace('/&[^; ]{0,6}.?/e', "((substr('\\0',-1) == ';') ? '\\0' : '&amp;'.substr('\\0',1))", 

Возможно, анализируемый XML-файл может быть слишком большим для синтаксического анализатора. Но вы можете попробовать передать LIBXML_PARSEHUGE в качестве опции – что помогло в моем случае.

У меня была эта проблема с 13 МБ-файлами и она была решена, включив параметр LIBXML_PARSEHUGE :

 $xml = new SimpleXMLElement($contents, LIBXML_PARSEHUGE); 

ПРИМЕЧАНИЕ. Использование ini_set в 1 ГБ не помогло решить мою проблему, потому что содержимое PARSED занимало больше, чем это.

Более радикальный подход – использование других библиотек для STREAM, а не LOAD WHOLE FILE (парсер SAX или DOM-парсер), например XML Streamer