ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ошибок Π² XML-Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ…

Ошибки ΠΏΡ€ΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅ XML-Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ функциями модуля libxml, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ΄Π°Π²ΠΈΡ‚ΡŒ всС XML-ошибки, Π° Π·Π°Ρ‚Π΅ΠΌ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΊΠ°ΠΆΠ΄ΡƒΡŽ ΠΎΡˆΠΈΠ±ΠΊΡƒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ.

ΠžΠ±ΡŠΠ΅ΠΊΡ‚ LibXMLError, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ функция libxml_get_errors(), содСрТит ряд свойств, Π² Ρ‚ΠΎΠΌ числС сообщСниС, Π½ΠΎΠΌΠ΅Ρ€ строки ΠΈ ΠΊΠΎΠ»ΠΎΠ½ΠΊΡƒ, ΠΈΠ»ΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ, ошибки.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #1 Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° XML-строки с Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΌ синтаксисом

<?php

libxml_use_internal_errors
(true);

$sxe = simplexml_load_string("<?xml version='1.0'><broken><xml></broken>");

if (!
$sxe) {
echo
"Ошибка Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ XML\n";

foreach(
libxml_get_errors() as $error) {
echo
"\t", $error->message;
}
}

?>

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°:

Ошибка Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ 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

Π‘ΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ Ρ‚Π°ΠΊΠΆΠ΅

οΌ‹Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΡ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ 3 notes

up
21
openbip at gmail dot com ΒΆ
16 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) {"
up
3
1337 at netapp dot com ΒΆ
10 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.
http://php.net/manual/en/class.domdocument.php#domdocument.props.recover
up
4
tuxedobob ΒΆ
11 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.