Я нахожусь в написании парсера и стараюсь делать хорошую обработку ошибок с исключениями.
Следующий пример кода:
<?php $xml = <<<XML <?xml version="1.0"?> <rootElem> XML; $reader = new XMLReader(); $reader->xml($xml, null, LIBXML_NOERROR | LIBXML_NOWARNING); $reader->read(); 
Выдает:
 PHP Warning: XMLReader::read(): An Error Occured while reading in /Users/evert/code/xml/errortest.php on line 11 PHP Stack trace: PHP 1. {main}() /Users/evert/code/xml/errortest.php:0 PHP 2. XMLReader->read() /Users/evert/code/xml/errortest.php:11 
Добавление:
 libxml_use_internal_errors(true); 
Не имеет никакого эффекта.
  Моя цель – проверить ошибки позже (с помощью libxml_get_errors() ) и выбросить исключение.  Я считаю, что единственным решением является использование оператора молчания ( @ ), но это похоже на плохую идею. 
  Обратите внимание, что когда я не LIBXML константы LIBXML и не использую libxml_use_internal_errors , я получаю другую ошибку, например: 
 PHP Warning: XMLReader::read(): /Users/evert/code/xml/:2: parser error : Extra content at the end of the document in /Users/evert/code/xml/errortest.php on line 11 
Это говорит о том, что основная библиотека libxml действительно подавляет ошибку, но в XMLReader все равно возникает ошибка.
  Похоже, нет способа подавить предупреждение, кроме использования @ , поскольку источник php для read() имеет следующие строки: 
 retval = xmlTextReaderRead(intern->ptr); if (retval == -1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "An Error Occured while reading"); RETURN_FALSE; } else { RETURN_BOOL(retval); } 
  Таким образом, только фактические ошибки синтаксического анализа внутри xmlTextReaderRead() подавляются libxml_use_internal_errors(true);  или параметры, переданные в XMLReader::xml() . 
Из моего понимания XMLReader, чтобы проверить документ, необходимо выполнить один полный проход по всему документу.
Что я делаю:
 // Enable internal libxml errors libxml_use_internal_errors(true); $xml = new \XMLReader(); $xsd='myfile.xsd'; $xml->open('myfile.xml'); $xml->setSchema ($xsd); // Conduct full pass through document. The only reason is to force validation. while (@$xml->read()) { }; // empty loop if (count(libxml_get_errors ())==0) { echo "provided xml is well formed and xsd-valid"; // Now you can start processing without @ as document was validated against xsd and is xml-wellformed } else echo "provided xml is wrong and/or not xsd-valid. stopping"; 
Конечно, вы можете проверить ошибки внутри пустого цикла, а затем сразу же после первой ошибки сломаться. Я заметил, что XMLReader не полностью сбой после первой ошибки – он продолжается и приносит множество проблем, которые полезны. Иногда может быть полезно распечатать все обнаруженные проблемы вместо обработки прерывания после первой проблемы.
Моя самая большая проблема заключается в том, что функция isValid существует в XMLReader 🙂 Я думаю, что это на самом деле своего рода обходной путь, но он работает очень хорошо и проверяет до того, как обработка соответствует 95% случаев использования XMLReader, поскольку она используется для обработки больших XML-коллекций.