simplexml_load_file

(PHP 5, PHP 7, PHP 8)

simplexml_load_file 将 XML 文件解释为对象

描述

simplexml_load_file(
    string $filename,
    ?string $class_name = SimpleXMLElement::class,
    int $options = 0,
    string $namespace_or_prefix = "",
    bool $is_prefix = false
): SimpleXMLElement|false

将给定文件中的格式良好的 XML 文档转换为对象。

参数

filename

XML 文件的路径

class_name

您可以使用此可选参数,以便 simplexml_load_file() 返回指定类的对象。该类应该扩展 SimpleXMLElement 类。

options

按位 OR libxml 选项常量

namespace_or_prefix

命名空间前缀或 URI。

is_prefix

true 如果 namespace_or_prefix 是前缀,false 如果它是 URI;默认值为 false

返回值

返回一个 objectSimpleXMLElement,其中包含 XML 文档中包含的数据的属性,或在失败时返回 false

警告

此函数可能会返回布尔值 false,但也可能返回一个非布尔值,该值计算为 false。请阅读有关 布尔值 的部分以了解更多信息。使用 === 运算符 来测试此函数的返回值。

错误/异常

为 XML 数据中发现的每个错误生成一个 E_WARNING 错误消息。

提示

使用 libxml_use_internal_errors() 来抑制所有 XML 错误,并使用 libxml_get_errors() 来迭代这些错误。

示例

示例 #1 解释 XML 文档

<?php
// 文件 test.xml 包含一个 XML 文档,其中有一个根元素
// 以及至少一个元素 /[root]/title。

if (file_exists('test.xml')) {
$xml = simplexml_load_file('test.xml');

print_r($xml);
} else {
exit(
'Failed to open test.xml.');
}
?>

此脚本将在成功时显示

SimpleXMLElement Object
(
  [title] => Example Title
  ...
)

此时,您可以开始使用 $xml->title 和任何其他元素。

参见

添加注释

用户贡献的注释 31 个注释

61
ricardo at ricardomartins dot info
11 年前
有时我们的 xml 具有连字符节点,例如

<my_xml>
<some-node>value</some-node>
</my_xml>

您需要使用
<?php
$simpleXmlObj
->{'some-node'}
?>

而不是
<?php
$simpleXmlObj
->some-node;
?>
33
wouter at code-b dot nl
17 年前
要正确地从 CDATA 中提取值,请确保通过使用强制转换运算符将 SimpleXML 元素强制转换为字符串值

<?php
$xml
= '<?xml version="1.0" encoding="UTF-8" ?>
<rss>
<channel>
<item>
<title><![CDATA[Tom & Jerry]]></title>
</item>
</channel>
</rss>'
;

$xml = simplexml_load_string($xml);

// echo 会为您进行强制转换
echo $xml->channel->item->title;

// 但 vardump(或 print_r)不会!
var_dump($xml->channel->item->title);

// 所以将 SimpleXML 元素强制转换为 'string' 可以解决此问题
var_dump((string) $xml->channel->item->title);
?>

以上将输出

Tom & Jerry

object(SimpleXMLElement)#4 (0) {}

string(11) "Tom & Jerry"
11
sirgrayjn at gmail dot com
7 年前
// 迁移或使用本地机器时要小心
// 用于测试/开发。

// Windows 目录分隔符:"\" 和 "/"
// 您可能会混合使用分隔符 "C:\somedir\www/img/bg.jpg"。

// 混合使用分隔符的路径在其他函数中可以正常工作
// 但 simplexml_load_file() 在混合使用分隔符时会失败。

// 示例
include("C:\dir\my.php"); // 工作(Windows)
include("C:\dir/my.php"); // 工作(Windows)混合使用
include("C:/dir/my.php"); // 工作(Windows、Linux)
simplexml_load_file("C:\dir\my.php"); // 工作
simplexml_load_file("C:\dir/my.php"); // 混合使用时失败
simplexml_load_file("C:/dir/my.php"); // 工作
7
neil art neilanddeb dort com
14 年前
由于我的 XML 文件的编码是 UTF-8,而
我的网页的编码是 iso-8859-1,我得到了一些奇怪的字符,例如 ’ 而不是右单引号。

这个解决方案很难找到,但实现起来却很简单。

http://uk3.php.net/manual/en/function.iconv.php

使用 iconv() 函数,您可以从一种编码转换为另一种编码,TRANSLIT 选项似乎最适合我的需要。这是我的示例

<?php
// 将字符串从 utf-8 转换为 iso8859-1
$horoscope = iconv( "UTF-8", "ISO-8859-1//TRANSLIT", $horoscope );
?>

我在这个页面上找到了解决方案...
http://tinyurl.com/lm39xc
希望这有帮助
1
visualmind at nospam dot php dot net
2 年前
这有时会被忽略,但如果你的 XML 节点格式为
<prefix:element />

你需要确保将 [命名空间或前缀] 参数和 [isPrefix] 参数设置为 true。另外,在调用元素时,你需要避免添加前缀(如果前缀已经设置),所以在上面的例子中,“prefix:element”应该添加为“element”,但在保存时会自动添加前缀。

如果在加载或对象构造期间没有设置前缀,加载将无法正确获取节点,你将无法直接调用元素,因此 $xml->{'prefix:element'} 也不起作用。
2
mario
15 年前
如果你想要在你的对象中使用 CDATA,你应该使用 LIBXML_NOCDATA

<?php
$xml
= simplexml_load_file($file_xml, 'SimpleXMLElement',LIBXML_NOCDATA);

print_r($xml);
?>
2
raduispas at gmail dot com
13 年前
如果你想要检查这个函数何时失败,请确保用 === 而不是 == 来比较返回值

<?php
$url
= 'http://www.example.com';
$xml = simpleXML_load_file($url,"SimpleXMLElement",LIBXML_NOCDATA);
if(
$xml === FALSE)
{
// 处理错误
}
else {
// 执行操作 }
?>

否则,即使文档是正常的,你也可能会一直得到 FALSE。希望这能帮助到某人 ;)
1
siraic at gmail dot com
1 年前
LibXML 通常使用文件大小的十倍的内存来读取文件,而这种内存使用量在很大程度上超出了 PHP 保护的内存限制。
0
tg at debian dot org
2 年前
尽管该函数的文档中有说明,但它并不接受所有路径名。

$ php -r 'print_r( simplexml_load_file("%25.xml"));'
PHP Warning: simplexml_load_file(): I/O warning : failed to load external entity "%25.xml" in Command line code on line 1
0
Rich
8 年前
我偶然发现了这个问题:一个包含简单字符串的单一元素变成了一个字符串,但一个包含 *空格* 的单一元素变成了一个数组,其中包含一个元素,即空格字符串。

我相信对于 XML 专家来说,这很明智且奇妙,但这确实让我很困惑,我认为它也可能让其他人感到困惑。

<?php
$parsed
= simplexml_load_string('<container><space> </space><blank></blank><string>hello</string></container>');
$content = json_decode(json_encode($parsed),TRUE);
var_dump($content);
/* 输出结果为:
array(3) {
'space' => array(1) { ← 没有预料到这个!
[0] => string(1) " "
}
'blank' => array(0) { }
'string' => string(5) "hello"
}
*/
0
l [DOT] anzinger [AT] gmail [DOT] com
16 年前
如果你不希望 CDATA 值被转义,只需使用 LIBXML_NOCDATA 作为第 3 个参数加载 XML。

注意:这需要 PHP 版本 >= 5.1.0 才能正常工作。

示例

<?php simplexml_load_file('xmldatei.xml', null, LIBXML_NOCDATA); ?>
0
info at evasion dot cc
18 年前
假设你已经将一个 XML 文件加载到 $simpleXML_obj 中。
结构如下

SimpleXMLElement Object
(

[node1] => SimpleXMLElement Object
(
[subnode1] => value1
[subnode2] => value2
[subnode3] => value3
)

[node2] => SimpleXMLElement Object
(
[subnode4] => value4
[subnode5] => value5
[subnode6] => value6
)

)

在对象中搜索特定节点时,可以使用此函数

<?php

function &getXMLnode($object, $param) {
foreach(
$object as $key => $value) {
if(isset(
$object->$key->$param)) {
return
$object->$key->$param;
}
if(
is_object($object->$key)&&!empty($object->$key)) {
$new_obj = $object->$key;
$ret = getCfgParam($new_obj, $param);
}
}
if(
$ret) return (string) $ret;
return
false;
}
?>

因此,如果你想要获取 subnode4 的值,可以使用此函数,如下所示

<?php
$result
= getXMLnode($simpleXML_obj, 'subnode4');
echo
$result;
?>

它将显示 "value4"
-1
kannan at 99deals dot in
11 年前
如果你有一些节点包含特殊字符,它们将无法正确加载

例如,请查看以下节点
<node:number>1538-7445</node:number>
<node:coverDisplayDate>Sep 1 2012 12:00:00:000AM</node:coverDisplayDate>

你必须将 : 更改为其他特殊字符,例如 -,才能正确转换它

正确的节点
<node-number>1538-7445</node-number>
<node-coverDisplayDate>Sep 1 2012 12:00:00:000AM</node-coverDisplayDate>

我在调试时浪费了宝贵的时间。请注意这一点。?
-1
fdouteaud at gmail dot com
18 年前
如果你使用 simplexml 数据直接填充你的 MySQL 数据库(使用 MYSQLi 和绑定参数),请注意。

来自 simplexml 的数据是对象,而 MySQLi 的绑定参数函数不喜欢对象!(这会导致一些内存泄漏,并可能导致 Apache/PHP 崩溃)

为了正确执行此操作,你必须将你的值转换为正确的类型(字符串、整数...)然后再将它们传递给 MySQLi 的绑定方法。
我在文档中没有找到这一点,这给我带来了很多头痛。
-1
tuxedobob
9 年前
有时你可能会尝试加载一个文件,但它会抱怨实体并抛出一个解析错误。

如果是这样,请检查问题文件是否不包含一个没有对应实体引用的&符号。

如果包含,或者你想谨慎行事,那么不要使用 simplexml_load_file,而是尝试以下方法

$file = file_get_contents('stuff.xml');
$temp = preg_replace('/&(?!(quot|amp|pos|lt|gt);)/', '&amp;', $file);
$xml = simplexml_load_string($temp) or die("xml not loading");

将文件读入一个字符串中,在任何不是字符实体一部分的&符号后添加“amp;”,然后将字符串解析为 XML。
-2
fusionstream at gmail dot com
12 年前
如果你要加载很多文件,这可能会减慢你的页面加载速度。

要设置超时,可以使用 file_get_context,然后使用 simplexml_load_string

<?php

$fp
= fopen('http://www.example.com/rss', false, stream_create_context(array('http' => array('timeout', '1.5'))));

if (
$fp) {
print_r( simplexml_load_string($fp) );
} else {
echo
"The request timed out";
}
?>
-1
php at werner dash ott dot de
17 年前
使 SimpleXMLElement 对象在会话中保存。

除了无法在会话中保存之外,SimpleXMLElement 对象甚至可能在尝试重新进入会话时导致 session_start() 函数崩溃!

为了解决这个问题,我使用了以下模式。核心思想是在会话调用之间将 SimpleXMLElement 对象转换为字符串表示形式,该字符串表示形式当然可以在会话中保存。

<?php
//
// SimpleXMLElement 对象的会话保存处理
// (适用于/测试 PHP 5.1.5 和 PHP 5.2.1)
// myClass 模式允许方便地访问
// XML 结构,同时进行会话保存
//
class myClass
{
private
$o_XMLconfig = null;
private
$s_XMLconfig = '';

public function
__construct($args_configfile)
{
$this->o_XMLconfig = simplexml_load_file($args_configfile);
$this->s_XMLconfig = $this->o_XMLconfig->asXML();
}
// __construct()

public function __destruct()
{
$this->s_XMLconfig = $this->o_XMLconfig->asXML();
unset(
$this->o_XMLconfig); // 否则此对象将崩溃
// 后续调用
// session_start()!
} // __destruct()

public function __wakeup()
{
$this->o_XMLconfig = simplexml_load_string($this->s_XMLconfig);
}
// __wakeup()

} // class myClass
?>
-2
jamie at splooshmedia dot co dot uk
14 年前
一个围绕 simplexml_load_file 的包装器,用于在 XML 服务器超时或出现 500 错误等时绕过讨厌的错误消息。

<?php
function loadXML2($domain, $path, $timeout = 30) {

/*
用法:

$xml = loadXML2("127.0.0.1", "/path/to/xml/server.php?code=do_something");
if($xml) {
// 加载 xml 文档
} else {
// 失败。显示友好错误消息。
}
*/

$fp = fsockopen($domain, 80, $errno, $errstr, $timeout);
if(
$fp) {
// 发出请求
$out = "GET $path HTTP/1.1\r\n";
$out .= "Host: $domain\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);

// 获取响应
$resp = "";
while (!
feof($fp)) {
$resp .= fgets($fp, 128);
}
fclose($fp);
// 检查状态是否为 200
$status_regex = "/HTTP\/1\.\d\s(\d+)/";
if(
preg_match($status_regex, $resp, $matches) && $matches[1] == 200) {
// 将 xml 加载为对象
$parts = explode("\r\n\r\n", $resp);
return
simplexml_load_string($parts[1]);
}
}
return
false;

}
?>
-3
sean at aliencreations dot com
13 年前
如果您发现使用 simplexml_load_file() 时收到 500 错误,但您可以通过浏览器手动访问 xml/rss feed,那么您的脚本可能被用户代理嗅探器阻止。

在您的 xml 调用之前添加此代码以解决此问题

<?php

ini_set
("user_agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");
ini_set("max_execution_time", 0);
ini_set("memory_limit", "10000M");

$rss = simplexml_load_file($feed_url);

?>
-1
genialbrainmachine at NOSPAM dot tiscali dot it
18 年前
Micro$oft Word 使用非标准字符,这些字符在使用 simplexml_load_file 时会造成问题。
许多系统在其实现的 ISO-8859-1 中包含非标准 Word 字符。因此,包含这些字符的 XML 文档可能对许多浏览器来说看起来格式良好(即)。但是,如果您尝试使用 simplexml_load_file 加载这种文档,您将遇到一些麻烦。
我相信这与 htmlentites 中讨论的完全相同的问题。以下关于 htmlentites 的注释在这里也很有意思(按相反的顺序给出,以提供历史记录)
http://it.php.net/manual/en/function.htmlentities.php#26379
http://it.php.net/manual/en/function.htmlentities.php#41152
http://it.php.net/manual/en/function.htmlentities.php#42126
http://it.php.net/manual/en/function.htmlentities.php#42511
-2
Kyle
17 年前
关于 2006 年 4 月 7 日的匿名用户

有一种方法可以取回 HTML 标签。例如

<?xml version="1.0"?>
<intro>
欢迎来到 <b>Example.com</b>!
</intro>

<?php
// 我使用 @ 以便在加载失败时它不会在错误消息中输出我的 XML 的内容。内容可能是密码,所以只是为了安全起见。
$xml = @simplexml_load_file('content_intro.xml');
if (
$xml) {
// asXML() 将保留 HTML 标签,但它也将保留父标签 <intro>,因此我用 str_replace 将它们剥离。如果有很多标签,您也可以使用 preg_replace。
$intro = str_replace(array('<intro>', '</intro>'), '', $xml->asXML());
} else {
$error = "无法加载 intro XML 文件。";
}
?>

使用这种方法,有人可以更改 content_intro.xml 中的 intro 并确保 HTML 格式良好,不会破坏整个网站设计。
-3
cryonyx at cerebrate dot ru
15 年前
如果您有一个 XML 文件,其中在一级包含一系列同名元素,simplexml 会错误地处理它们,并且不允许使用 foreach() 遍历数组。据我所知,这是由 PHP xml_parser 引起的问题(参见:http://ru2.php.net/manual/ru/function.xml-parser-create.php#53188)。

要避免这种情况,只需使用 count() 并使用 for() 遍历数组。

示例

<params>
<param>
<name>version.shell</name>
<value>1.0</value>
</param>
<param>
<name>version.core</name>
<value>1.0</value>
</param>
<param>
<name>file.lang</name>
<value>vc.lang</value>
</param>
...
</params>

<?php
$filename
= '...';
$xml = simplexml_load_file($filename);
$p_cnt = count($xml->param);
for(
$i = 0; $i < $p_cnt; $i++) {
$param = $xml->param[$i];
...;
}
?>
-4
skutter at imprecision dot net
18 年前
看来 SimpleXML 不支持 CDATA... 我把这个小正则表达式函数拼凑在一起,以便在尝试使用 simplexml_load_file/simplexml_load_string 之类解析 XML 之前对 CDATA 进行排序。希望它能帮助到某些人,并且很乐意听到更好的解决方案。(当然,除了 *不* 使用 SimpleXML!;)

它查找任何 <![CDATA [文本和 HTML 等在此处]]> 元素,对封装的数据进行 htmlspecialchar() 处理,然后剥离 "<![CDATA [" 和 "]]>" 标签。

<?php
函数 simplexml_unCDATAise($xml) {
$new_xml = NULL;
preg_match_all("/\<\!\[CDATA \[(.*)\]\]\>/U", $xml, $args);

如果 (
is_array($args)) {
如果 (isset(
$args[0]) && isset($args[1])) {
$new_xml = $xml;
为了 (
$i=0; $i<count($args[0]); $i++) {
$old_text = $args[0][$i];
$new_text = htmlspecialchars($args[1][$i]);
$new_xml = str_replace($old_text, $new_text, $new_xml);
}
}
}

返回
$new_xml;
}

//用法:
$xml = '你的 XML 带有 CDATA...';
$xml = simplexml_unCDATAise($xml);
$xml_object = simplexml_load_string($xml);
?>
-4
Nanuit at ossi dot at
13 年前
一个在使用代理后使用 simplexml_load_file 的非常有帮助的小函数

<?php
函数 getXMLfromURL($url) {
$Proxy = getenv("HTTP_PROXY");

如果 (
strlen($Proxy) > 1) {
$r_default_context = stream_context_get_default ( 数组
(
'http' => 数组(
'proxy' => $Proxy,
'request_fulluri' => True,
),
)
);
libxml_set_streams_context($r_default_context);
}
$daten = simplexml_load_file($url);
返回 (
$daten);
}
?>

其中 HTTP_PROXY 设置为例如:tcp://proxy:8080
-3
Smokey
14 年前
对于嵌套和相同名称的值,我做了一些小修改,以便从谷歌地理编码获取和显示多个值。当没有完全匹配时,它会以以下格式返回所有接近匹配的值(这是一个简略版本):

<Response>
<Placemark id="1">
<address> New York 24, NY, USA</address>
<AddressDetails>
..................
</AddressDetails>
<Point>
<coordinates>-73.5850086,40.7207442,0</coordinates>
</Point>
</Placemark>
<Placemark id="2">
<address>New York 27, NY, USA</address>
<AddressDetails>
...................
</AddressDetails>
<Point>
<coordinates>-72.8987835,40.8003588,0</coordinates>
</Point>
</Placemark>
<Placemark id="3">
<address>Cedar Place School, 20 Cedar Pl, Yonkers, NY 10705, USA</address>
<AddressDetails>
..................
</AddressDetails>
<Point>
<coordinates>-73.8966320,40.9256520,0</coordinates>
</Point>
</Placemark>
</Response>

<?php
// 获取并分解结果,然后将它们存储在 $var 中
$Address = "99999 parkplace, new york, NY";
$urladdress = urlencode($Address);
$Base_url = "http://maps.google.com/maps/geo?q=";
$urlParts = "&output=xml";
$urlrequest = $Base_url . $urladdress . $urlParts;
$xml = simplexml_load_file($urlrequest);
$num = "0";
foreach (
$xml->Response->Placemark as $value){
$num++;
$GeoFindAdd{$num} = $value->address;
$GeoFindCords{$num} = $value->Point->coordinates;
}

// 结果的简单显示
echo "找到 ",$num," 个可能的地理数据集 <br>";
$CountNumResults = "0";
为了 ( ;
$num > 0; $num--){
$CountNumResults++;
echo
$countnum,"<br> 地址 = ",$GeoFindAdd{$num},"<br> 坐标 = ",$GeoFindCords{$num},"<br>";
}
echo
"END";
?>
-3
Anonymous
18 年前
使用该脚本发现 simplexml_load_file() 会删除 XML 文件中的任何 HTML 格式,并且只会加载到一定深度。如果你的 XML 文件太深,它会返回一个布尔值 false。
-3
info at evasion dot cc
18 年前
抱歉,之前函数中有一个错误
<?php
函数 &getXMLnode($object, $param) {
遍历(
$object 作为 $key => $value) {
如果(isset(
$object->$key->$param)) {
返回
$object->$key->$param;
}
如果(
is_object($object->$key)&&!empty($object->$key)) {
$new_obj = $object->$key;
// 必须在那里使用 getXMLnode 函数(递归)
$ret = getXMLnode($new_obj, $param);

}
}
如果(
$ret) 返回 (字符串) $ret;
返回
false;
}
?>
-3
rex111 at bigmir dot net
7 年前
获取所有标签及其值。(递归)

<?php
$xml
= simplexml_load_file('settings.xml');

函数
all_tag($xml){
$i=0; $name = "";
遍历 (
$xml 作为 $k){
$tag = $k->getName();
$tag_value = $xml->$tag;
如果 (
$name == $tag){ $i++; }
$name = $tag;
echo
$tag .' '.$tag_value[$i].'<br />';
// 递归
all_tag($xml->$tag->children());
}
}

all_tag($xml);
?>
-5
mark
18 年前
如果对象的属性为空,则不会创建数组。这是一个正确传输的 object2array 版本。

<?php
function object2array($object)
{
$return = NULL;

if(
is_array($object))
{
foreach(
$object as $key => $value)
$return[$key] = object2array($value);
}
else
{
$var = get_object_vars($object);

if(
$var)
{
foreach(
$var as $key => $value)
$return[$key] = ($key && !$value) ? NULL : object2array($value);
}
else return
$object;
}

return
$return;
}
?>
-13
guego dot ol at ig dot com dot br
13 年前
完整分析 XML。

<?php
$xml
= simplexml_load_file('file.xml');

foreach(
$xml as $key0 => $value){
echo
"..1..[$key0] => $value";
foreach(
$value->attributes() as $attributeskey0 => $attributesvalue1){
echo
"________[$attributeskey0] = $attributesvalue1";
}
echo
'<br />';
////////////////////////////////////////////////
foreach($value as $key => $value2){
echo
"....2.....[$key] => $value2";
foreach(
$value2->attributes() as $attributeskey => $attributesvalue2){
echo
"________[$attributeskey] = $attributesvalue2";
}
echo
'<br />';
////////////////////////////////////////////////
foreach($value2 as $key2 => $value3){
echo
".........3..........[$key2] => $value3";
foreach(
$value3->attributes() as $attributeskey2 => $attributesvalue3){
echo
"________[$attributeskey2] = $attributesvalue3";
}
echo
'<br />';
////////////////////////////////////////////////
foreach($value3 as $key3 => $value4){
echo
"...................4....................[$key3] => $value4";
foreach(
$value4->attributes() as $attributeskey3 => $attributesvalue4){
echo
"________[$attributeskey3] = $attributesvalue4";
}
echo
'<br />';
////////////////////////////////////////////////
foreach($value4 as $key4 => $value5){
echo
".....................5......................[$key4] => $value5";
foreach(
$value5->attributes() as $attributeskey4 => $attributesvalue5){
echo
"________[$attributeskey4] = $attributesvalue5";
}
echo
'<br />';
////////////////////////////////////////////////
foreach($value5 as $key5 => $value6){
echo
"......................6.......................[$key5] => $value6";
foreach(
$value6->attributes() as $attributeskey5 => $attributesvalue6){
echo
"________[$attributeskey5] = $attributesvalue6";
}
echo
'<br />';
}}}}}
echo
'<br />';
}
?>
-4
knl at bitflop dot com
14 年前
如果需要将 SimpleXML 中的数据解析到会话变量中,请记住首先将数据定义为字符串。

如果不这样做,您将收到“节点不再存在”的警告,指向您的 session_start() 函数。

这将起作用

<?php

$new_version
= simplexml_load_file('http://example.com/version.xml');
$_SESSION['current_version'] = (string)$new_version->version;

?>
To Top