DOMDocument::loadXML

(PHP 5, PHP 7, PHP 8)

DOMDocument::loadXML 从字符串加载 XML

描述

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

从字符串加载 XML 文档。

参数

source

包含 XML 的字符串。

options

按位 ORlibxml 选项常量

返回值

成功时返回 true,失败时返回 false

错误/异常

如果传递空字符串作为 source,将生成警告。此警告不是由 libxml 生成,也不能使用 libxml 的错误处理函数处理。

变更日志

版本 描述
8.3.0 此函数现在具有一个暂定的 bool 返回类型。
8.0.0 现在以静态方式调用此函数将抛出 Error。以前,会引发 E_DEPRECATED

示例

示例 #1 创建文档

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

参见

添加备注

用户贡献的备注 12 备注

46
Gustavo L. Fabro
10 年前
始终牢记,使用默认参数,此函数无法很好地处理大型文件,即如果文本节点的长度超过 10Mb,它可能会引发异常,指出

DOMDocument::loadXML(): 内部错误在实体的文档末尾存在额外内容

即使 XML 是正常的。

原因是 lixml 的 parserInternals.h 中的定义
#define XML_MAX_TEXT_LENGTH 10000000

要允许该函数处理更大的文件,请将 LIBXML_PARSEHUGE 作为选项传递,它将正常工作

$domDocument->loadXML($xml, LIBXML_PARSEHUGE);
4
Stuart Grimshaw
17 年前
options 参数的可能值可以在此处找到

http://us3.php.net/manual/en/ref.libxml.php#libxml.constants
7
Adrian Wiik
4 年前
对 loadXML() 的调用将覆盖先前在 DOMDocument 构造函数中创建的 XML 声明。如果加载的 XML 中没有 XML 声明,并且您无法控制源(例如,如果 XML 来自 Web 服务),这可能会导致编码问题。要解决此问题,请在加载 XML 后使用 DOMDocument 的 'encoding' 类属性设置编码。示例

糟糕的情况

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

test.php
$xmlDoc = new DOMDocument("1.0", "utf-8"); // 使用 loadXML() 时,此处参数会被覆盖,实际上并不相关
$testXML = file_get_contents("test.xml");
$xmlDoc->loadXML($testXML);
// 打印内容到文件或日志函数以获取输出,使用 $xmlDoc->saveXML()

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

好的情况

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

test.php
$xmlDoc = new DOMDocument("1.0", "utf-8"); // 使用 loadXML() 时,此处参数会被覆盖,实际上并不相关
$testXML = file_get_contents("test.xml");
$xmlDoc->loadXML($testXML);
$xmlDoc->encoding = "utf-8";
// 打印内容到文件或日志函数以获取输出,使用 $xmlDoc->saveXML()

输出
<?xml version="1.0" encoding="utf-8"?>
<test>
<hello>hi</hello>
<field>ø</field>
</test>
14
Gavin Sinai gsinai at gmx dot net
17 年前
当 xml 格式不正确时,loadXml 会报告错误而不是抛出异常。如果您尝试在 try...catch 语句中执行 loadXml(),这很烦人。显然这是特性,而不是错误,因为这符合规范。

如果您希望捕获异常而不是生成报告,您可以执行以下操作

<?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;
}

?>

在函数 HandleXmlError() 中返回 false 会导致回退到默认错误处理程序。
6
shaoyu73 at gmail dot com
17 年前
earth at anonymous dot com,

出于某种原因,需要将 preserveWhiteSpace 属性设置为 false 才能使 formatOutput 正确工作。

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

这将以美观的格式输出。
2
Marc Liyanage
17 年前
文档说明 loadXML 可以以静态方式调用,但这具有误导性。此功能似乎是一个特殊情况的技巧,根据 http://bugs.php.net/bug.php?id=41398.,其使用似乎并不鼓励。

如果代码在启用了 E_STRICT 错误报告的情况下运行,则以静态方式调用该方法将失败并出现错误。

文档应该更改以明确说明静态调用违反了推荐做法,并且在 E_STRICT 下将无法工作。
2
earth at anonymous dot com
18 年前
请注意,loadXML 会裁剪开头和结尾的空格和换行符。

在使用 loadXML 和 appendChild 将 XML 块添加到现有文档时,您可能希望在 XML 块末尾和输出文件中的下一行(通常是结束标签)之间强制换行符

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

虽然据说不应该使用 DOM 来创建“漂亮”的 XML 输出,但这是我在测试中为了获得可读结果而努力解决的一个问题。另一个解决方案是使用 createDocumentFragment() -> appendXML(..XML-Chunk..) 代替,它似乎不会像 DOMDocument -> loadXML() 那样删除换行符。
3
olalonde at NOSPAM dot gmail dot com
16 年前
出于某种原因,当您将 DOMDocument 的属性“recover”设置为 true 时,使用“@”来屏蔽 loadXml() 抛出的错误将不起作用。

以下是我的解决方法

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

您也可以简单地执行以下操作:error_reporting(0); 然后将 error_reporting 设置回其原始状态。
3
jazzslider at hotmail dot com
17 年前
当使用 loadXML() 解析包含实体引用(例如,&nbsp;)的字符串时,请确保这些实体引用通过使用 DOCTYPE 声明得到正确声明;否则,loadXML() 将无法解释该字符串。

示例
<?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();
?>

鉴于以上代码,PHP 将发出关于实体“nbsp”未正确声明的警告。此外,对 saveXML() 的调用将仅返回原始处理指令的修剪版本......所有其他内容都消失了,这一切都是因为未声明的实体。

相反,首先显式声明实体
<?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();
?>

由于“nbsp”实体在 DOCTYPE 中定义,PHP 不再发出该警告;该字符串现在是格式良好的,loadXML() 可以完全理解它。

您也可以以相同的方式使用对外部 DTD 的引用(例如,<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">),如果您需要对包含许多不同可能实体的许多不同文档执行此操作,这一点尤其重要。

另外,需要注意的是...由 createEntityReference() 创建的实体引用不需要这种显式声明。
2
remacg
15 年前
不要这样做

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

只需使用

loadHTML() 而不是 loadXML()。
2
mp at webfactory dot de
18 年前
虽然 loadXML() 期望其输入具有引导 XML 处理指令以推断使用的编码,但在(非 XML)HTML 文档中没有这样的概念。因此,DOM 函数底层的 libxml 库会查看 <META> 标签以确定使用的编码。

请参见 http://xmlsoft.org/encoding.html.
-11
szalma dot laszlo at zengo dot eu
14 年前
从字符串加载工作正常,没有 <?xml version="1.0" encoding="utf-8"?> 标头,但在这种情况下,xmlEncoding 不会被设置,这会导致 utf-8 字符(国际字符和特殊字符)在使用 saveXML() 保存时被编码为十六进制实体!
To Top