PHP Conference Japan 2024

DOMDocument::load

(PHP 5, PHP 7, PHP 8)

DOMDocument::load 从文件加载XML

描述

public DOMDocument::load(string $filename, int $options = 0): bool

从文件加载XML文档。

警告

使用正斜杠的Unix风格路径可能会导致Windows系统上的性能显著下降;在这种情况下,请务必调用realpath()

参数

filename

XML文档的路径。

options

按位OR libxml选项常量

返回值

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

错误/异常

如果将空字符串作为filename参数传递,或者命名了一个空文件,则会生成警告。此警告不是由libxml生成的,无法使用libxml的错误处理函数处理。

变更日志

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

示例

示例 #1 创建文档

<?php
$doc
= new DOMDocument();
$doc->load('book.xml');
echo
$doc->saveXML();
?>

参见

添加注释

用户贡献注释 14 条注释

Jonas Due Vesterheden
15 年前
我在通过HTTP加载文档时遇到问题。我收到的错误如下所示

警告:DOMDocument::load(http://external/document.xml): failed to open stream: HTTP request failed! HTTP/1.1 500 Internal Server Error

该文档可以在浏览器中和使用wget加载。问题在于,在我的系统(OS X和Linux)上,DOMDocument::load()没有发送任何User-Agent标头,由于某种奇怪的原因,这使得Microsoft-IIS/6.0返回500错误。

解决方案可以在https://php.net/manual/en/function.libxml-set-streams-context.php 找到

<?php
$opts
= array(
'http' => array(
'user_agent' => 'PHP libxml agent',
)
);

$context = stream_context_create($opts);
libxml_set_streams_context($context);

// 通过HTTP请求文件
$doc = DOMDocument::load('http://www.example.com/file.xml');
?>
hh dot lohmann at yahoo dot de
17 年前
BadGuy 的注释可能令人困惑,因为他描述的并非该方法的特殊属性。PHP 始终在本地文件系统中工作,这意味着如果您想使用其他系统中的资源,或者——这确实是 BadGuy 的问题——需要由其他程序或进程处理的资源,则必须在代码中明确声明和管理。PHP 在这方面只是一个相当普通的程序。

BadGuy 的解决方案是使用“http 包装器”来获取来自另一个进程的输出(请参阅 PHP 手册中的“包装器”)。这样做时,必须遵守 http 调用的适当语法。
admin at tijnema dot tijnema dot info
17 年前
回复 BadGuy [at] BadGuy [dot] nl

正如您在第一个示例中所说,当 news.php 文件位于同一服务器上时,http://my.beautiful-website.com/xmlsource/news.php 将不起作用,但您应该使用 https://127.0.0.1/xmlsource/news.phphttp://127.0.0.1/xmlsource/news.php
the_N_Channel
16 年前
注意,如果在 <?xml version="1.0" ?> 声明之前文件的开头有注释,则无法成功加载!
BadGuy [at] BadGuy [dot] nl
17 年前
请注意,此方法在执行任何远程操作之前都使用本地文件系统。“缺点”是,如果您执行以下操作
<?php
$xml
= new DOMDocument;
$xml->load("xmlsource/news.php");
?>

这不会使该方法读取 news.php 文件的实际输出(大概是有效的 xml 数据),而是读取文件内容(显然这是 php 代码)。因此,这将返回一个错误,指出 news.php 缺少 xml 声明,可能还缺少 xml 开始标签

可行的方法如下

<?php
$xml
= new DOMDocument;
$xml->load("http://my.beautiful-website.com/xmlsource/news.php");
?>

这将强制使用 http 请求来获取此文件,而不是仅在本地读取它,并且该文件仅返回代码
sainthyoga2003 at gmail dot com
12 年前
在默认示例中

<?php
$doc
= new DOMDocument();
$doc->load('book.xml');
echo
$doc->saveXML();
?>

您必须输入 book.xml 的绝对路径,否则 load 函数将返回 false。
Raf-sns
1年前
小心“preserveWhiteSpace”选项

$dom = new DOMDocument;
// false -> 保留空格
// true -> 将所有条目放在同一行
$dom->preserveWhiteSpace = false; // 保留空格!
sainthyoga2003 at gmail dot com
13 年前
我找到了针对 xml:id 警告的部分解决方案,它解释在这个地址:https://fosswiki.liip.ch/display/BLOG/GetElementById+Pitfalls

那里解释说
ID必须是有效的NCName,例如,这意味着第一个字母不能是数字。

我的 xml:id 中有一个数字。:D
_ michael
14年前
XHTML 和实体:[email protected] 在下面提出的解决方案对我不起作用。我在多个服务器(LAMPP 和 WAMPP)上进行了检查——在每个服务器上,使用 LIBXML_DTDLOAD 选项调用 loadXML() 都会触发对 DTD 的外部请求。这是一个坏消息。

如果关闭 allow_url_fopen,则对 DTD 的请求将失败并发出警告。如果启用它,则请求会失败,因为这些 w3c URL 返回 503 服务不可用。

无论哪种情况,HTML 实体仍然会生成警告。

据我所知,最好的解决方案是简单地忽略警告并使用“@”抑制它们。我不建议使用 loadHTML() 而不是 loadXML() 来解析 XHTML——是的,您可以消除实体问题,但是 loadHTML() 在解析时会更改源代码(尝试“修复”它,即使没有需要修复的内容)。
syntaxiko
15 年前
如果使用 XML DOM PECL 模块,则函数将无法工作
[email protected]
19年前
假设您想从 .XSD 文件动态加载数组。此方法正是您需要的。只需记住在 xpath 等中使用实际的 xs: 部分。

所有其他“加载”方法都会出错。

<?php
$attributes
= array();
$xsdstring = "/htdocs/api/xsd/common.xsd";
$XSDDOC = new DOMDocument();
$XSDDOC->preserveWhiteSpace = false;
if (
$XSDDOC->load($xsdstring))
{
$xsdpath = new DOMXPath($XSDDOC);
$attributeNodes =
$xsdpath->
query('//xs:simpleType[@name="attributeType"]')
->
item(0);
foreach (
$attributeNodes->childNodes as $attr)
{
$attributes[ $attr->getAttribute('value') ] = $attr->getAttribute('name');
}
unset(
$xsdpath);
}
print_r($attributes);
?>
_ michael
14年前
load() 将处理非 ASCII 字符,具体取决于 XML 声明的细节,但方式有些出人意料。人们可能会认为声明 '<?xml version="1.0" encoding="UTF-8"?>' 和 '<?xml version="1.0"?>' 的处理方式相同,因为 UTF-8 无论如何都是默认编码。但事实并非如此。

* 如果存在 XML 声明*明确*定义编码,则非 ASCII 字符将保持不变。
* 如果 XML 声明没有明确定义编码,或者 XML 声明缺失,则非 ASCII 字符将转换为数字实体。

因此,文档

<?xml version="1.0"?>
<root><nonascii>ä</nonascii></root>

将转换为

<?xml version="1.0"?>
<root><nonascii>&#xE4;</nonascii></root>

如果根本没有 XML 声明,也会发生同样的情况。另一方面,文档

<?xml version="1.0" encoding="UTF-8"?>
<root><nonascii>ä</nonascii></root>

将保持原样。

此行为也适用于 loadXML()。
[email protected]
16 年前
如果您要加载 xml 以便针对内部 dtd 验证它,并且您遇到验证问题,则可能与缺少 LIBXML 常量有关。

我在根级 dom 文档中找到了“[email protected]”的这篇文章,我认为它在这里可能更有用
从 PHP 5.1 开始,可以使用常量而不是专有的 DomDocument 属性来设置 libxml 选项。

DomDocument->resolveExternals 等效于设置
LIBXML_DTDLOAD
LIBXML_DTDATTR

DomDocument->validateOnParse 等效于设置
LIBXML_DTDLOAD
LIBXML_DTDVALID

鼓励 PHP 5.1 用户使用新的常量。

示例
<?php
$dom
= new DOMDocument;
// 解析外部文件
$dom->load($file, LIBXML_DTDLOAD|LIBXML_DTDATTR);
// 或
// 对 DTD 进行验证
$dom->load($file, LIBXML_DTDLOAD|LIBXML_DTDVALID);
$dom->validate();
?>
[email protected]
15 年前
您可以通过使用 LIBXML_DTDLOAD 选项轻松避免有关 &nbsp; 引用警告。

<?php

$html
= <<<EOF
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<p>&nbsp;</p>
</body>
</html>
EOF;

// 此代码完美运行。
$dom = new DOMDocument();
$dom->loadXML($html, LIBXML_DTDLOAD);
print
$dom->saveXML();

// 此代码会产生警告。
$dom = new DOMDocument();
$dom->loadXML($html);
print
$dom->saveXML();

?>

另请参阅:https://php.net/manual/en/libxml.constants.php

请注意,libxml 将检测到您的 DTD 可通过 /etc/xml/catalog 本地访问。因此,不必担心这会导致您的 DOM 加载进行外部网络请求。
To Top