DOMDocument::loadXML

(PHP 5, PHP 7, PHP 8)

DOMDocument::loadXML 文字列から XML を読み込む

説明

public DOMDocument::loadXML(string $source, int $options = 0): bool

XML ドキュメントを文字列から読み込みます。

パラメータ

source

XML を含む文字列。

options

libxml オプション定数ビット OR で連結したもの。

戻り値

成功した場合に true を、失敗した場合に false を返します。

エラー / 例外

空の文字列を source に渡すと、警告が発生します。 この警告は libxml が発するものではないので、libxml のエラー処理関数では処理できません。

変更履歴

バージョン 説明
8.3.0 この関数の仮の戻り値の型が、bool になりました。
8.0.0 この関数を static メソッドとしてコールすると、 Error がスローされるようになりました。 これより前のバージョンでは、 E_DEPRECATED が発生していました。

例1 ドキュメントを作成する

<?php
$doc
= new DOMDocument();
$doc->loadXML('<root><node/></root>');
echo
$doc->saveXML();
?>

参考

add a note add a note

User Contributed Notes 12 notes

up
40
Gustavo L. Fabro
11 years ago
Always remember that with the default parameters this function doesn't handle well large files, i.e. if a text node is longer than 10Mb it can raise an exception stating:

DOMDocument::loadXML(): internal error Extra content at the end of the document in Entity

even though the XML is fine.

The cause is a definition in parserInternals.h of lixml:
#define XML_MAX_TEXT_LENGTH 10000000

To allow the function to process larger files, pass the LIBXML_PARSEHUGE as an option and it will work just fine:

$domDocument->loadXML($xml, LIBXML_PARSEHUGE);
up
11
Gavin Sinai gsinai at gmx dot net
18 years ago
loadXml reports an error instead of throwing an exception when the xml is not well formed. This is annoying if you are trying to to loadXml() in a try...catch statement. Apparently its a feature, not a bug, because this conforms to a spefication.

If you want to catch an exception instead of generating a report, you could do something like

<?php
function HandleXmlError($errno, $errstr, $errfile, $errline)
{
    if (
$errno==E_WARNING && (substr_count($errstr,"DOMDocument::loadXML()")>0))
    {
        throw new
DOMException($errstr);
    }
    else
        return
false;
}

function
XmlLoader($strXml)
{
   
set_error_handler('HandleXmlError');
   
$dom = new DOMDocument();
   
$dom->loadXml($strXml);   
   
restore_error_handler();
    return
$dom;
}

?>

Returning false in function HandleXmlError() causes a fallback to the default error handler.
up
4
Adrian Wiik
5 years ago
A call to loadXML() will overwrite the XML declaration previously created in the constructor of DOMDocument. This can cause encoding problems if there is no XML declaration in the loaded XML and you don't have control over the source (e.g. if the XML is coming from a webservice). To fix this, set encoding AFTER loading the XML using the 'encoding' class property of DOMDocument. Example:

Bad situation:

test.xml:
<test>
    <hello>hi</hello>
    <field>ø</field>
</test>

test.php:
$xmlDoc = new DOMDocument("1.0", "utf-8"); // Parameters here are overwritten anyway when using loadXML(), and are not really relevant
$testXML = file_get_contents("test.xml");
$xmlDoc->loadXML($testXML);
// Print the contents to a file or in a log function to get the output, using $xmlDoc->saveXML()

Output:
<?xml version="1.0"?>
<test>
    <hello>hi</hello>
    <field>&#xF8;</field>
</test>

Good situation:

test.xml:
<test>
    <hello>hi</hello>
    <field>ø</field>
</test>

test.php:
$xmlDoc = new DOMDocument("1.0", "utf-8"); // Parameters here are overwritten anyway when using loadXML(), and are not really relevant
$testXML = file_get_contents("test.xml");
$xmlDoc->loadXML($testXML);
$xmlDoc->encoding = "utf-8";
// Print the contents to a file or in a log function to get the output, using $xmlDoc->saveXML()

Output:
<?xml version="1.0" encoding="utf-8"?>
<test>
    <hello>hi</hello>
    <field>ø</field>
</test>
up
6
shaoyu73 at gmail dot com
17 years ago
earth at anonymous dot com,

preserveWhiteSpace property needs to be set to false for formatOutput to work properly, for some reason.

$dom = new DOMDocument;
$dom->preserveWhiteSpace = false;
$dom->loadXML($xmlStr);
...
$element->appendChild(...);
...
$dom->formatOutput = true;
$xmlStr = $dom->saveXML();
echo $xmlStr;

This would format the output nicely.
up
3
olalonde at NOSPAM dot gmail dot com
16 years ago
For some reason, when you set DOMDocument's property 'recover' to true, using '@' to mask errors thrown by loadXml() won't work.

Here's my workaround:

function maskErrors() {}
set_error_handler('maskErrors');
$dom->loadXml($xml);
restore_error_handler();

You could also simply do this: error_reporting(0); and then set back error_reporting to its original state.
up
1
earth at anonymous dot com
18 years ago
Note that loadXML crops off beginning and trailing whitespace and linebreaks.

When using loadXML and appendChild to add a chunk of XML to an existing document, you may want to force a linebreak between the end of the XML chunk and the next line (usually a close tag) in the output file:

$childDocument = new DOMDocument;
$childDocument>preserveWhiteSpace = true;
$childDocument->loadXML(..XML-Chunk..);
$mNewNode = $mainDOcument->importNode($childDocument->documentElement, true);
$ParentNode->appendChild($mNewNode);
$ParentNode->appendChild($mainDocument->createTextNode("\\n  ");

Although it is said that DOM should not be used to make 'pretty' XML output, it is something I struggled with to get something that was readable for testing.  Another solution is to use the createDocumentFragment()->appendXML(..XML-Chunk..) instead, which seems not to trim off linebreaks like DOMDocument->loadXML() does.
up
1
jazzslider at hotmail dot com
17 years ago
When using loadXML() to parse a string that contains entity references (e.g., &nbsp;), be sure that those entity references are properly declared through the use of a DOCTYPE declaration; otherwise, loadXML() will not be able to interpret the string.

Example:
<?php
$str
= <<<XML
<?xml version="1.0" encoding="iso-8859-1"?>
<div>This&nbsp;is a non-breaking space.</div>
XML;

$dd1 = new DOMDocument();
$dd1->loadXML($str);

echo
$dd1->saveXML();
?>

Given the above code, PHP will issue a Warning about the entity 'nbsp' not being properly declared.  Also, the call to saveXML() will return nothing but a trimmed-down version of the original processing instruction...everything else is gone, and all because of the undeclared entity.

Instead, explicitly declare the entity first:
<?php
$str
= <<<XML
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE root [
<!ENTITY nbsp "&#160;">
]>
<div>This&nbsp;is a non-breaking space.</div>
XML;

$dd2 = new DOMDocument();
$dd2->loadXML($str);

echo
$dd2->saveXML();
?>

Since the 'nbsp' entity is defined in the DOCTYPE, PHP no longer issues that Warning; the string is now well-formed, and loadXML() understands it perfectly.

You can also use references to external DTDs in the same way (e.g., <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">), which is particularly important if you need to do this for many different documents with many different possible entities.

Also, as a sidenote...entity references created by createEntityReference() do not need this kind of explicit declaration.
up
2
Stuart Grimshaw
17 years ago
Possible values for the options parameter can be found here:

http://us3.php.net/manual/en/ref.libxml.php#libxml.constants
up
2
Marc Liyanage
17 years ago
The documentation states that loadXML can be called statically, but this is misleading. This feature seems to be a special case hack and its use seems to be discouraged according to http://bugs.php.net/bug.php?id=41398.

Calling the method statically will fail with an error if the code runs with E_STRICT error reporting enabled.

The documentation should be changed to make it clear that a static call is against recommended practice and won't work with E_STRICT.
up
1
mp at webfactory dot de
18 years ago
While loadXML() expects its input to have a leading XML processing instruction to deduce the encoding used, there's no such concept in (non-XML) HTML documents. Thus, the libxml library underlying the DOM functions peeks at the <META> tags to figure out the encoding used.

See http://xmlsoft.org/encoding.html.
up
0
remacg
15 years ago
Instead of doing this:

<?php
$str
= <<<XML
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE root [
<!ENTITY nbsp "&#160;">
]>
<div>This&nbsp;is a non-breaking space.</div>
XML;

$dd2 = new DOMDocument();
$dd2->loadXML($str);

echo
$dd2->saveXML();
?>

simply use:

loadHTML() rather than loadXML().
up
-8
szalma dot laszlo at zengo dot eu
15 years ago
Loading from a string works fine without the <?xml version="1.0" encoding="utf-8"?> header, but in this case the xmlEncoding won't be set, and this makes the utf-8 characters (international, and special characters) to be encoded as hexa entities when saved with saveXML()!
To Top