Пуленепробиваемый SimpleXMLElement

Всем известно, что мы всегда должны использовать методы DOM вместо регулярных выражений для извлечения содержимого из HTML, но у меня такое чувство, что я никогда не смогу доверять расширению SimpleXML или подобным.

Я сейчас кодирую реализацию OpenID и пытался использовать SimpleXML для обнаружения HTML, но мой самый первый тест (с alixaxel.myopenid.com) дал много ошибок:

Warning: simplexml_load_string() [function.simplexml-load-string]: Entity: line 27: parser error : Opening and ending tag mismatch: link line 11 and head in E:\xampplite\htdocs\index.php on line 6

Warning: simplexml_load_string() [function.simplexml-load-string]: </head> in E:\xampplite\htdocs\index.php on line 6

Warning: simplexml_load_string() [function.simplexml-load-string]: ^ in E:\xampplite\htdocs\index.php on line 6

Warning: simplexml_load_string() [function.simplexml-load-string]: Entity: line 64: parser error : Entity 'copy' not defined in E:\xampplite\htdocs\index.php on line 6

Warning: simplexml_load_string() [function.simplexml-load-string]: &copy; 2008 <a href="http://janrain.com/">JanRain, Inc.</a> in E:\xampplite\htdocs\index.php on line 6

Warning: simplexml_load_string() [function.simplexml-load-string]: ^ in E:\xampplite\htdocs\index.php on line 6

Warning: simplexml_load_string() [function.simplexml-load-string]: Entity: line 66: parser error : Entity 'trade' not defined in E:\xampplite\htdocs\index.php on line 6

Warning: simplexml_load_string() [function.simplexml-load-string]: myOpenID&trade; and the myOpenID&trade; website are in E:\xampplite\htdocs\index.php on line 6

Warning: simplexml_load_string() [function.simplexml-load-string]: ^ in E:\xampplite\htdocs\index.php on line 6

Warning: simplexml_load_string() [function.simplexml-load-string]: Entity: line 66: parser error : Entity 'trade' not defined in E:\xampplite\htdocs\index.php on line 6

Warning: simplexml_load_string() [function.simplexml-load-string]: myOpenID&trade; and the myOpenID&trade; website are in E:\xampplite\htdocs\index.php on line 6

Warning: simplexml_load_string() [function.simplexml-load-string]: ^ in E:\xampplite\htdocs\index.php on line 6

Warning: simplexml_load_string() [function.simplexml-load-string]: Entity: line 77: parser error : Opening and ending tag mismatch: link line 8 and html in E:\xampplite\htdocs\index.php on line 6

Warning: simplexml_load_string() [function.simplexml-load-string]: </html> in E:\xampplite\htdocs\index.php on line 6

Warning: simplexml_load_string() [function.simplexml-load-string]: ^ in E:\xampplite\htdocs\index.php on line 6

Warning: simplexml_load_string() [function.simplexml-load-string]: Entity: line 78: parser error : Premature end of data in tag head line 3 in E:\xampplite\htdocs\index.php on line 6

Warning: simplexml_load_string() [function.simplexml-load-string]: in E:\xampplite\htdocs\index.php on line 6

Warning: simplexml_load_string() [function.simplexml-load-string]: ^ in E:\xampplite\htdocs\index.php on line 6

Warning: simplexml_load_string() [function.simplexml-load-string]: Entity: line 78: parser error : Premature end of data in tag html line 2 in E:\xampplite\htdocs\index.php on line 6

Warning: simplexml_load_string() [function.simplexml-load-string]: in E:\xampplite\htdocs\index.php on line 6

Warning: simplexml_load_string() [function.simplexml-load-string]: ^ in E:\xampplite\htdocs\index.php on line 6

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

И, пожалуйста, не предлагайте использовать Tidy, я думаю, что расширение работает медленно и недоступно на многих системах.


person Alix Axel    schedule 22.07.2010    source источник


Ответы (2)


Вы можете загрузить HTML с помощью loadHTML DOM, а затем импортировать результат в SimpleXML.

IIRC, он по-прежнему будет давиться некоторыми вещами, но примет почти все, что существует в реальном мире сломанных веб-сайтов.

$html = '<html><head><body><div>stuff & stuff</body></html>';

// disable PHP errors
$old = libxml_use_internal_errors(true);

$dom = new DOMDocument;
$dom->loadHTML($html);

// restore the old behaviour
libxml_use_internal_errors($old);

$sxe = simplexml_import_dom($dom);
die($sxe->asXML());
person Josh Davis    schedule 22.07.2010
comment
Уфф! Так-то лучше... Является ли это решение пуленепробиваемым? Могу ли я доверять ему анализ любого документа? - person Alix Axel; 22.07.2010
comment
@Alix, скорее всего, не какой-либо документ. Если HTML слишком сломан, то он слишком сломан. Но для большинства сломанных HTML это должно работать. Альтернативой может быть использование XmlReader. Это анализатор вытягивания, который позволяет вам определить, что делать с каким элементом. Существует также ряд параметров конфигурации для базового расширения libxml, которые вы можете использовать, чтобы влиять на синтаксический анализ. - person Gordon; 22.07.2010

вы всегда можете попробовать синтаксический анализатор SAX... Немного более устойчивый к ошибкам.

Может быть не так эффективен для больших XML.

person Eamorr    schedule 22.07.2010