文字

DOMDocument::loadXML

(PHP 5, PHP 7)

DOMDocument::loadXML Load XML from a string

说明

public mixed DOMDocument::loadXML ( string $source [, int $options = 0 ] )

Loads an XML document from a string.

参数

source

The string containing the XML.

options

Bitwise OR of the libxml option constants.

返回值

成功时返回 TRUE , 或者在失败时返回 FALSE 。 If called statically, returns a DOMDocument 或者在失败时返回 FALSE .

错误/异常

If an empty string is passed as the source, a warning will be generated. This warning is not generated by libxml and cannot be handled using libxml's error handling functions.

此方法可以被静态调用,但会抛出一个 E_STRICT 错误。

范例

Example #1 Creating a Document

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

Example #2 Static invocation of loadXML

<?php
// Issues an E_STRICT error
$doc  DOMDocument :: loadXML ( '<root><node/></root>' );
echo 
$doc -> saveXML ();
?>

参见

  • DOMDocument::load() - Load XML from a file
  • DOMDocument::save() - Dumps the internal XML tree back into a file
  • DOMDocument::saveXML() - Dumps the internal XML tree back into a string

用户评论:

[#1] Gustavo L. Fabro [2013-11-14 16:41:38]

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);

[#2] szalma dot laszlo at zengo dot eu [2009-10-27 08:14:27]

Loading from a string works fine without the  <?phpxml 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()!

[#3] remacg [2009-02-26 07:33:20]

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().

[#4] olalonde at NOSPAM dot gmail dot com [2008-03-21 17:00:32]

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.

[#5] Stuart Grimshaw [2007-06-26 13:57:27]

Possible values for the options parameter can be found here:

http://us3.php.net/manual/en/ref.libxml.php#libxml.constants

[#6] Marc Liyanage [2007-06-18 07:08:43]

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.

[#7] jazzslider at hotmail dot com [2007-04-30 13:14:11]

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.

[#8] shaoyu73 at gmail dot com [2007-03-15 20:53:58]

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.

[#9] Gavin Sinai gsinai at gmx dot net [2006-08-30 07:34:39]

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.

[#10] mp at webfactory dot de [2006-08-08 08:26:54]

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.

[#11] earth at anonymous dot com [2006-04-12 02:28:44]

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.

上一篇: 下一篇: