Быстрая версия:
Каков стандартный (новаторский? Любой?) способ обнаружения и обработки ошибок, выдаваемых XMLReader из-за неправильного формата файла, в частности, неэкранированных символов. Привлечение внимания с помощью Tidy (и т. Д.) Не очень привлекательный вариант, кто-нибудь знает способ просто пропустить оскорбительный узел и двигаться дальше?
Описательная версия:
Мы все знаем, что это не XML, если он неправильно сформирован, но давайте будем честными — такое случается. Клиент регулярно загружает массивные (50-100 МБ+) xml-файлы, которые необходимо прочитать в mysql. XMLReader — очевидный выбор, и мы написали оболочку, которая хорошо подходит для наших нужд.
Иногда возникает ошибка, и функция read() не завершает импорт — дерьмо! Это почти всегда неэкранированный символ (например, «&»), который сбивает все с толку. В большинстве случаев мы бы просто попросили клиента позвонить поставщику данных и потребовать исправить его дефектный файл. К сожалению, поставщики данных не всегда услужливы и/или своевременны. Было бы замечательно, если бы мы могли просто поймать ошибку и сразу перейти к следующему узлу.
Я потратил довольно много времени, пытаясь прочитать / взломать это, и не могу найти ничего стоящего. Я упускаю что-то очевидное?
Этот ТАК вопрос казался многообещающим, но он просто не дал никаких результатов. Кажется, что передача 1 должна попросить Reader восстановиться, но мы просто не видим никаких попыток/различных сообщений об ошибках и т. д. Вот соответствующий код, описывающий подход:
$xml->open($file, null, LIBXML_NOERROR | LIBXML_NOWARNING | 1);
Я всегда мог выполнить предварительную обработку с помощью Tidy, но должен быть способ получше.
Я рассмотрел несколько более «креативных» подходов, таких как прослушивание следующего Read() с помощью try/catch после завершения логики для текущего узла, но это кажется в лучшем случае неуклюжим. Также кажется, что может быть потенциал в эмуляции Read() с пользовательской функцией/оболочкой, которая помогает перемещаться по узлам и включает обработку ошибок, но у меня есть ощущение, что я слишком упрощаю вещи.
Итак, подведем итог: когда read() не работает, как я могу поймать ошибку и двигаться дальше? Есть ли шанс, что мы сможем увидеть, какая ошибка возникает (по крайней мере, сообщение, которое выдал бы XMLReader)?
$xml = new XMLReader();
$xml->open($file);
while ($xml->read()) {
}