Bulletproofing 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, я думаю, что расширение медленное, и оно недоступно во многих системах.

Вы можете загрузить 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()); 

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

Не может быть столь же эффективным на большом XML.