CascadiaPHP 2024

Behandlung von XML-Fehlern

Die Behandlung von XML-Fehlern beim Laden von Dokumenten ist eine sehr einfache Sache. Durch die Verwendung der libxml-Funktionalität ist es möglich, alle XML-Fehlermeldungen beim Laden des Dokuments zu unterdrücken und danach über die aufgetretenen Meldungen zu iterieren.

Das libXMLError-Objekt, das von libxml_get_errors() zurückgegeben wird, hat verschiedene Eigenschaften. Dazu gehören message, line und column (Position) des jeweiligen Fehlers.

Beispiel #1 Laden eines defekten XML-Strings

$sxe = simplexml_load_string("<?xml version='1.0'><broken><xml></broken>");
if (
$sxe === false) {
"Laden des XML fehlgeschlagen\n";
libxml_get_errors() as $error) {
"\t", $error->message;

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

Laden des XML fehlgeschlagen
    Blank needed here
    parsing XML declaration: '?>' expected
    Opening and ending tag mismatch: xml line 1 and broken
    Premature end of data in tag broken line 1

add a note

User Contributed Notes 4 notes

openbip at gmail dot com
14 years ago
Note that "if (! $sxe) {" may give you a false-negative if the XML document was empty (e.g. "<root />"). In that case, $sxe will be:

object(SimpleXMLElement)#1 (0) {

which will evaluate to false, even though nothing technically went wrong.

Consider instead: "if ($sxe === false) {"
1337 at netapp dot com
8 years ago
If you need to process the content of your broken XML-doc you might find this interesting. It has blown past a few simple corruptions for me.
9 years ago
Now that the /e modifier is considered deprecated in preg_replace, you can use a negative lookahead to replace unescaped ampersands with &amp; without throwing warnings:

$str = preg_replace('/&(?!;{6})/', '&amp;', $str);

You probably should have been doing this before /e was deprecated, actually.
Jacob Tabak
14 years ago
If you are trying to load an XML string with some escaped and some unescaped ampersands, you can pre-parse the string to ecsape the unescaped ampersands without modifying the already escaped ones:
= preg_replace('/&[^; ]{0,6}.?/e', "((substr('\\0',-1) == ';') ? '\\0' : '&amp;'.substr('\\0',1))", $s);
To Top