2010-07-22 8 views
5

Jeder weiß, dass wir immer DOM-Techniken anstelle von Regex verwenden sollten, um Inhalte aus HTML zu extrahieren, aber ich habe das Gefühl, dass ich der SimpleXML-Erweiterung oder ähnlichen niemals vertrauen kann.Bulletproofing SimpleXMLElement

Ich bin Codierung eine OpenID Implementierung gerade jetzt, und ich versuchte, SimpleXML mit der HTML-Entdeckung zu tun - aber mein erster Test (mit alixaxel.myopenid.com) ergab eine Menge von Fehlern:

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 

Ich erinnere mich, es gab eine Möglichkeit, SimpleXML immer eine Datei parsen zu lassen, unabhängig davon, ob das Dokument Fehler enthält oder nicht - ich kann mich zwar nicht an die spezifische Implementierung erinnern, aber ich denke, dass es DOMDocument verwendet. Was ist der beste Weg, um sicherzustellen, dass SimpleXML jedes Dokument analysiert?

Und bitte nicht Tidy, ich denke, die Erweiterung ist langsam und es ist nicht auf vielen Systemen verfügbar.

Antwort

10

Sie können den HTML-Code mit DOM's loadHTML laden und dann das Ergebnis in SimpleXML importieren.

IIRC, es wird immer noch auf einige Zeug ersticken, aber es wird so ziemlich alles akzeptieren, was in der realen Welt der gebrochenen Websites existiert.

$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()); 
+0

Uff! Das ist besser ... Ist diese Lösung * kugelsicher *? Kann ich darauf vertrauen, dass jedes Dokument analysiert wird? –

+0

@Alix wahrscheinlich nicht * irgendein * Dokument. Wenn der HTML-Code zu kaputt ist, ist er zu kaputt. Aber für die meisten HTML-Dateien sollte das funktionieren. Eine Alternative wäre die Verwendung von XmlReader. Das ist ein Pull-Parser, mit dem Sie definieren können, was mit welchem ​​Element zu tun ist. Es gibt auch eine Reihe von Konfigurationsoptionen für die zugrunde liegende libxml-Erweiterung, mit der Sie das Parsing beeinflussen können. – Gordon

0

Sie könnten immer einen SAX-Parser versuchen ... Ein bisschen robuster gegenüber Fehlern.

Möglicherweise nicht so effizient auf großen XML.

Verwandte Themen