文字

Dealing with XML errors

Dealing with XML errors when loading documents is a very simple task. Using the libxml functionality it is possible to suppress all XML errors when loading the document and then iterate over the errors.

The libXMLError object, returned by libxml_get_errors() , contains several properties including the message, line and column (position) of the error.

Example #1 Loading broken XML string

<?php
libxml_use_internal_errors
( true );
$sxe  simplexml_load_string ( "<?xml version='1.0'><broken><xml></broken>" );
if (
$sxe  ===  false ) {
    echo 
"Failed loading XML\n" ;
    foreach(
libxml_get_errors () as  $error ) {
        echo 
"\t" $error -> message ;
    }
}
?>

以上例程会输出:

Failed loading XML
    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

参见

  • libxml_use_internal_errors()
  • libxml_get_errors()
  • libXMLError

用户评论:

[#1] 1337 at netapp dot com [2015-09-04 14:21:39]

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.
http://php.net/manual/en/class.domdocument.php#domdocument.props.recover

[#2] tuxedobob [2014-09-11 21:29:00]

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.

[#3] openbip at gmail dot com [2010-02-25 20:20:17]

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) {"

[#4] Jacob Tabak [2010-02-15 13:17:36]

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:
<?php
$s 
preg_replace('/&[^; ]{0,6}.?/e'"((substr('\\0',-1) == ';') ? '\\0' : '&amp;'.substr('\\0',1))"$s);
?>

上一篇: 下一篇: