SimpleXML 函数

目录

添加笔记

用户贡献笔记 37 笔记

18
help :-) @ theapotek :-) com
13 年前
如果您在访问 SimpleXML 文档中的 CDATA 时遇到问题,您不需要在使用 simplexml 加载之前使用 str_replace/preg_replace 替换 CDATA。

您可以改为这样做,所有 CDATA 内容将作为字符串合并到元素内容中。

$xml = simplexml_load_file($xmlfile,
'SimpleXMLElement', LIBXML_NOCDATA);
8
cmsa at gmx dot de
16 年前
我在实体方面遇到了问题。

我的第一个解决方案
我以这种方式保存数据
$ENTRY_->
addchild('Nachricht',htmlentities($_POST["blog"]));

XML 文件中存在这样的实体
<!ENTITY auml "&amp;auml">

我以这种方式加载数据
html_entity_decode($ENTRY->Nachname);

但保存后
加载 xml 文件后,实体条目
<!ENTITY auml "&amp;auml">
消失了。奇怪...

我的第二个解决方案
通过以这种方式保存数据
$ENTRY_->
addchild('Nachricht',htmlentities(htmlentities($_POST["blog"])));

现在我可以使用 html_entity_decode 加载它,而 XML 文件中没有
实体条目!
我用 äöü 测试了它。

希望对您有所帮助。
5
joel [from the website] purerave.com
17 年前
它没有在任何地方提到这一点,但从非有效字符串创建新的 SimpleXMLElement 对象会引发异常。它在 php 日志中看起来很丑,因为它将堆栈转储到多行中。

创建新的 SimpleXMLElement 对象的正确方法如下所示
<?php
$xmlstr
= ''; // 空字符串会引发异常
try {
$xml = new SimpleXMLElement($xmlstr);
} catch (
Exception $e) {
// 处理错误
echo '$xmlstr is not a valid xml string';
}
?>
4
brcavanagh AT NO SPAM hotmail.com
19 年前
如果您希望将 SimpleXML 用于读取 XML 文档以外的任何用途,您应该重新考虑,并使用 XML DOM 库。当您在 DOM 中实现足够多的实用程序来处理 SimpleXML 中的所有挫折时,您将违背使用 SimpleXML 的目的。有几个原因导致这种情况,并且已经存在许多解决方法,但主要问题是

1) 没有复杂的节点分配。您不能切换节点或替换它们。

2) 无法追加新的子节点

3) 每当您执行诸如 $new_node = $xml_doc->node 之类的操作时,即使您使用克隆方法,您也始终会获得引用,这会导致脚本崩溃。

除此之外,它是一个读取文档的好工具。
5
r dot m dot 0100101 at gmail dot com
11 年前
这是对 https://php.net/manual/en/ref.simplexml.php#103617 的函数的轻微调整。
他们提供的函数会将 simpleXML 转换为数组,但仅限于最高级别。一旦您将 is_array 检查与 is_object 结合使用,它应该将每个级别转换为数组(至少对我来说,它在 3 个级别上都做到了这一点)。

function simpleXmlObjectToArray ( $xmlObject, $out = array () )
{
foreach ( (array) $xmlObject as $index => $node )
$out[$index] = ( is_object ( $node ) || is_array($node) )
? simpleXmlObjectToArray ( $node )
: $node;

return $out;
}
祝您编程愉快!
6
William Fahria
11 年前
一个简单的实现
您可以将文本格式的直接 XML 传递给该函数。

function eoXML2Array($xmlContent, $out = array()){
$xmlObject = is_object($xmlContent) ? $xmlContent : simplexml_load_string($xmlContent);
foreach((array) $xmlObject as $index => $node)
$out[$index] = ( is_object($node) || is_array($node) ) ? eoXML2Array( $node ) : $node;
return $out;
}

用法:$your_array = eoXML2Array(您的 xml 文本);
5
paul at preinheimer dot com
19 年前
您好,

如果您想访问名称中带有连字符的元素(这在图书馆国会以及 NWS 提供的 XML 文档中很常见),您需要以稍微不同的方式处理它。

您可以使用 XPATH,它工作正常,但每次都会返回一个结果数组,即使只有一个结果也是如此。
例如

<?php
$xml
->xpath('/data/time-layout/start-valid-time');
?>

您也可以选择只封装包含连字符的元素名称
<?php $xml->data->{'time-layout'}->{'start-valid-time'} ?>

--

关于一个仅部分相关的说明,处理 SimpleXML 是我唯一一次在 PHP 中使用强制转换的时候。在遍历(foreach)有效时间时,回显元素工作得很好(它只是回显了适当的时间),将其分配给另一个变量会导致一个包含要分配时间的 SimpleXML 对象,而不是仅仅是时间本身。这通过将时间强制转换为字符串得到了解决

<?php
foreach($xml->data->{'time-layout'}->{'start-valid-time'} AS $time)
{
$weatherDates[] = (string) $time;
}
?>
4
brandonkirsch at gmail dot com
10 年前
与这里发布的其他笔记相反,SimpleXML *不能* 正确处理非 UTF8 编码的 XML 文档。

当使用扩展字符(即字节值大于 127)时,对于 PHP 5.2.17 或 5.5.1,正确声明和编码为“iso-8859-1”的 XML 文档将无法使用 SimpleXML 解析。

另一方面,DOMDocument 将正确解析传入的 iso-8859-1 XML 文档,并且还可以用于执行字符转换到 UTF8

$dom = new DOMDocument();

if($dom->loadXML($fileContents)){ // $fileContents 是声明中指定了 iso-8859-1 编码的 XML 文档
$dom->encoding = 'utf-8'; // 将文档编码转换为 UTF8
return $dom->saveXML(); // 返回有效的 UTF8 编码的 XML
6
andrvm
16 年前
<?php
/**
* 使用 XPath 删除节点/节点 xml
*
* @param SimpleXMLElement $xml
* @param string XPath $path
* @param string ('one'|'child'|'all') $multi
*
* 用法:
*
* 示例 xml 文件 - http://ru2.php.net/manual/ru/ref.simplexml.php
*
* $xml = simplexml_load_file($xmlfile);
*
* //1. 只删除一个节点(不含子节点)
* // $path 必须返回一个(唯一)不含子节点的节点
* removeNode($xml, '//movie/rating[@type="thumbs"]');
*
* //2. 删除一个节点(含一个子节点)
* // $path 可以返回任何节点 - 只会删除第一个节点
* // 以及所有子节点
* removeNode($xml, '//characters', 'child')
*
* //3. 删除所有节点(含子节点)
* // $path 可以返回任何节点 - 会删除所有节点
* // 以及子节点
* removeNode($xml, '//rating', 'all')
*
* $xml->asXML($xmlfile);
*
*/
function removeNode($xml, $path, $multi='one')
{
$result = $xml->xpath($path);

# 针对错误的 $path
if (!isset($result[0])) return false;

switch (
$multi) {
case
'all':
$errlevel = error_reporting(E_ALL & ~E_WARNING);
foreach (
$result as $r) unset ($r[0]);
error_reporting($errlevel);
return
true;

case
'child':
unset(
$result[0][0]);
return
true;

case
'one':
if (
count($result[0]->children())==0 && count($result)==1) {
unset(
$result[0][0]);
return
true;
}

default:
return
false;
}
}
?>

p.s. 使用后(如果已删除所有节点)
<?php

function trimXml($xmlfile)
{
$dom = new DOMDocument();

$dom->preserveWhiteSpace = false;

if (!
$dom->load($xmlfile)) return false;

$dom->formatOutput = true;

if (!
$dom->save($xmlfile)) return false;

return
true;
}
?>
4
T CHASSAGNETTE t_chassagnette at yahoo dot fr
19 年前
另一种使用 SIMPLEXML 将 XML 文档解析为 PHP 数组的方法,灵感来自 Daniel FAIVRE!

<?php
function xml2php($xml)
{
$fils = 0;
$tab = false;
$array = array();
foreach(
$xml->children() as $key => $value)
{
$child = xml2php($value);

// 处理属性
foreach($node->attributes() as $ak=>$av)
{
$child[$ak] = (string)$av;

}

// 查看新子节点是否不在数组中
if($tab==false && in_array($key,array_keys($array)))
{
// 如果此元素已存在于数组中,我们将创建一个索引数组
$tmp = $array[$key];
$array[$key] = NULL;
$array[$key][] = $tmp;
$array[$key][] = $child;
$tab = true;
}
elseif(
$tab == true)
{
// 在现有数组中添加元素
$array[$key][] = $child;
}
else
{
// 添加一个简单元素
$array[$key] = $child;
}

$fils++;
}


if(
$fils==0)
{
return (string)
$xml;
}

return
$array;

}
?>
4
ngkongs at gmail dot com
16 年前
修复我之前发布的函数,有一个错误的引号位置

function implode2($glue="", $var){
if ($var){
foreach ($var as $value){
$array[]=strval($value);
}
return implode($glue, $array);
}
else return false;
}
5
Eric
11 年前
如果 SimpleXMLObject 包含一个数组,添加 is_array() 允许该函数继续挖掘对象。

<?php
function xml2array ( $xmlObject, $out = array () )
{
foreach ( (array)
$xmlObject as $index => $node )
$out[$index] = ( is_object ( $node ) || is_array ( $node ) ) ? xml2array ( $node ) : $node;

return
$out;
}
?>
3
Douglas Marsh
15 年前
SimpleXML 对于将 XML 数据加载/转换为本地 PHP 数据结构非常有用。我正在考虑对 SVG 进行粗略的搜索以获取宽度/高度,并且因为它确实是一个 XML 文件……我找到了一个超级简单的解析所需信息的方法

<?php
// 将不完整的 SVG 数据内联以提高可读性
$RawXML = <<< XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://www.example.com/dc"
xmlns:cc="http://www.example.com/cc"
xmlns:rdf="http://www.example.com/rdf"
xmlns:svg="http://www.example.com/svg"
xmlns="http://www.example.com/"
xmlns:sodipodi="http://www.example.com/sodipodi"
xmlns:inkscape="http://www.example.com/inkscape"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.46"
width="586.25"
height="743.75"
xml:space="preserve"
sodipodi:docname="some_svg_file.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<!-- 部分内容已删除以保持简短 -->
</svg>
XML;

$svg = new SimpleXMLElement($RawXML);

$height = $svg['height'];
$width = $svg['width'];

echo
"宽度 x 高度为: ${width} x ${height} \n";

?>
4
daniel dot oconnor at gmail dot com
18 年前
SimpleXML 处理命名空间,但这里没有很好的文档记录。

如果你想解析,例如,一个 open office 清单文件或一段 RDF/XML,你必须通过命名空间 URL 获取元素和属性。

示例
<?php
函数 display($in) {
if (
file_exists($in)) {
$xml = simplexml_load_file($in);
} else {
throw new
Exception($in . " 不存在");
}

$manifest = $xml->children('http://openoffice.org/2001/manifest');

foreach (
$manifest->xpath('//manifest:file-entry') as $file) {
foreach (
$file->attributes('http://openoffice.org/2001/manifest') as $key => $value) {
print
"键:" . $key . "\n";
print
"值:" . $value . "\n";
}
}

}
?>

文件: manifest.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE manifest:manifest PUBLIC "-//OpenOffice.org//DTD Manifest 1.0//EN" "Manifest.dtd">
<manifest:manifest xmlns:manifest="http://openoffice.org/2001/manifest">
<manifest:file-entry manifest:media-type="application/vnd.sun.xml.writer" manifest:full-path="/"/>
<manifest:file-entry manifest:media-type="application/vnd.sun.xml.ui.configuration" manifest:full-path="Configurations2/"/>
<manifest:file-entry manifest:media-type="application/binary" manifest:full-path="layout-cache"/>
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="content.xml"/>
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="styles.xml"/>
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="meta.xml"/>
<manifest:file-entry manifest:media-type="" manifest:full-path="Thumbnails/thumbnail.png"/>
<manifest:file-entry manifest:media-type="" manifest:full-path="Thumbnails/"/>
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="settings.xml"/>
</manifest:manifest>
5
onPHP5.com
16 年前
文档中没有说明,但 SimpleXML 会将所有文本转换为 UTF-8,如果源 XML 声明使用其他编码。例如,如果源具有以下 XML 声明

<?xml version="1.0" encoding="windows-1251" ?>

结果 SimpleXMLElement 中的所有文本将自动使用 UTF-8。
3
Arnaud Bienvenu
17 年前
从 PHP 5.1.4 开始,尝试迭代不存在的节点实际上会创建该节点。

<?
$xml = simplexml_load_string('<root></root>');
foreach($xml->b as $dummy);
echo $xml->asXML();
?>

结果

<?xml version="1.0"?>
<root><b/></root>

您可能认为这是一个错误,但 PHP 开发人员似乎认为这是一个特性:http://bugs.php.net/bug.php?id=39164
2
julien dot breiner at laposte dot net
12 年前
仅使用 SimpleXML 合并两个 XML

<?php
私有函数 mergeXML(&$base, $add)
{
$new = $base->addChild($add->getName());
foreach (
$add->attributes() as $a => $b) {
$new[$a] = $b;
}
foreach (
$add->children() as $child) {
$this->mergeXML($new, $child);
}
}
?>

使用:<?php mergeXML($xmlElement, simplexml_load_string($toMerge)) ?>
2
nelson_menezes at yahoo dot co dot uk
19 年前
请注意,SimpleXML 期望以 UTF-8 编码读写 XML。如果您的输入 XML 文件不是以 UTF-8 保存的,则需要在文件开头添加如下所示的行(调整为使用的任何编码)

<?xml version="1.0" encoding="ISO-8859-1" ?>

在输出方面,如果您不提供/处理 UTF-8,则需要使用 utf8_decode() [红色。但这仅适用于 ISO-8859-1,不适用于其他编码]。常见错误:http://bugs.php.net/bug.php?id=28154
3
k dot antczak at livedata dot pl
13 年前
一个快速代码片段,用于将 XML 对象转换为数组

<?php
函数 xml2array ( $xmlObject, $out = array () )
{
foreach ( (array)
$xmlObject as $index => $node )
$out[$index] = ( is_object ( $node ) ) ? xml2array ( $node ) : $node;

return
$out;
}
?>

玩得开心!;-)
1
james dot ellis at gmail dot com
15 年前
虽然 SimpleXML 是一款强大的工具,但使用它来处理和处理大型 XML 文档和字符串的开发人员应该仔细考虑其内存使用需求。
SimpleXML 要求在对树进行任何处理操作之前,整个 XML 树都可用 - 这需要整个树都在内存中。对于 40kb 的 XML 文件来说可以,但在处理超过 100MB 的文件时,您会看到性能下降,尤其是在服务器繁忙的情况下。

处理大型 XML 文件的另一种方法是 XMLReader 类,它以流式模式工作,这里提供了一个优秀的教程
http://www.ibm.com/developerworks/library/x-pullparsingphp.html

XML 是一种非常冗长的格式。如果您处理大型数据结构,尤其是在 Web 服务中,您真的需要将数据表示为 XML 树吗? - 其他序列化格式,如 JSON、序列化 PHP、Google Protocol Buffers (http://code.google.com/p/protobuf/) 甚至 CSV 在处理大型文件时可以显着减少处理时间、带宽和负载。110MB 的 XML 文件可以变为 65MB 的 CSV 文件,其中包含相同的数据,仅仅因为数据标识符(标签)在整个文档中只表示一次。
1
m0sh3 at hotmail dot com
16 年前
注意此类怪癖

<?php

$a
= new SimpleXMLElement('<a><b/></a>');

$a->b = 'test &amp; test';
$a->c = 'test &amp; test';

print_r($a);
/*
输出:

SimpleXMLElement Object
(
[b] => test & test
[c] => test &amp; test
)
*/
1
codje2 at lboro dot ac dot uk
17 年前
有时混合使用数据存储类型会很有用。这是一个非常简单的 SQL 到 XML 转换器。向它提供 SQL 查询,它会以 XML 格式输出结果。

第一个参数应该是 mysql_query 结果
(可选)第二个是每行的 XML 名称(即 XML 的第二层深度)
(可选)第三个是 XML 文档的名称,根名称

<?php
$result
=mysql_query("SELECT * FROM users");
sql_to_xml($result,"users","members");

函数
sql_to_xml($mysql_result,$row_name="row",$doc_name="root")
{

$xml= new SimpleXMLElement("<$doc_name></$doc_name>");
while(
$line=mysql_fetch_assoc($mysql_result))
{
$row=$xml->addChild($row_name);
foreach(
$line as $column => $value)
{
$row->$column="$value";
}
}
return
$xml->asXML();
}

?>
1
karsten dot bruch at bms-verlage dot de
16 年前
在创建新的 XML 文档并使用带变音符号的文本时

<?php $SimpleXMLElement->asXML(); ?>

将静默地不输出任何带有变音符号的内容。

在添加变音符号时使用 htmlentities() 来解决“问题”。
2
lordi at msdi dot ca
16 年前
如果您需要对从 simplexml 文档中提取的值进行数学计算,则可能需要将该值强制转换为浮点数以防止精度损失。这是一个示例

<?php
$objXML
= new SimpleXMLElement('<test x="-123.45"></test>');

//显示正确
echo $objXML['x']."\n";

//我们丢失了小数部分
echo $objXML['x'] + $objXML['x']."\n";

$x = $objXML['x'];

//如果我们强制转换金额,则此方法有效
echo (float)$objXML['x'] + (float)$objXML['x']."\n";

//在字符串上计算,没问题
echo "-123.45" + "-123.45";

?>

这是因为 $objXML['x'] 不是字符串(php 会自动强制转换),也不是浮点数,而是一个 SimpleXMLElement 对象。

“echo var_dump($x);” 将输出以下内容
~~
object(SimpleXMLElement)#3 (1) {
[0]=>
string(7) "-123.45"
}
~~

我在 php 上提交了一个 bug 请求,但他们给了我以下回复

~~
状态:不会修复

此行为由引擎而不是扩展定义。在对对象执行数学运算时,它们被视为整数。用户有责任将对象强制转换为适当的类型以保持正确的精度。
~~
2
anthony dot parsons at manx dot net
17 年前
如果您处理大量 HTML 或混合内容 XML,您可能希望使用 DOM 函数而不是 SimpleXML。例如
<?php
$html
= new SimpleXMLElement('<div><p>Some text, <a href="#">a link,</a> more text</p></div>');

echo
$html->p->a,"<br>\n"; // "a link,"
echo $html->p; // "Some text, more text" (!)
?>
在上面的示例中,由于 SimpleXML 表示数据的方式,无法重建原始标记。
2
php at NOSPAM dot coutch dot com
17 年前
在设置属性时发生内存泄漏,如示例(#示例 2134. 设置值)所示

这在 Web 脚本中可能不会被注意到(除非您进行大量的 XML 操作),但我遇到了我的独立脚本,该脚本处理大量 XML 文件。

以下代码将很快消耗内存

<?php
include 'example.php';

while (
true) {
$xml = new SimpleXMLElement($xmlstr);
$xml->movie[0]->characters->character[0]->name = 'Miss Coder';
}
?>

虽然这似乎正常运行

<?php
include 'example.php';

while (
true) {
$xml = new SimpleXMLElement($xmlstr);
$c = $xml->xpath("//character");
$c[0]->name = 'Miss Coder';
}
?>

这看起来像是 bug #38604,我刚刚确认在 6.0.0-dev(至少在 Windows 上)中它已修复。它在 5.2.1 或 5.2.2-dev(2/21 版本)中没有修复,因此对于 5.2 用户,请使用第二种形式以避免泄漏。
2
matt at mattbostock dot com
17 年前
使用 var_export 调试元素属性时要小心 - 它不起作用!始终使用 print() 或类似方法来检查元素属性的内容。
0
Pyetro Costa [pyetrosafe at gmail dot com]
5 年前
在查看了 "https://php.net/manual/en/ref.simplexml.php#103617" 的 xml2array 函数和 "https://php.net/manual/en/ref.simplexml.php # 112038 ",并且仍然对将空标签转换为 null 进行了一些更改... 我觉得有必要将结果作为一个对象来处理,保持数组像数组一样。最终找到了这个函数
<?php

private function xml2Object($xmlObject, $out = null) {
$out = (is_object($xmlObject) ? new \stdClass : array());
foreach ((array)
$xmlObject as $index => $node )
if (
is_array($out)) {
$out[$index] = (is_object($node) || is_array($node)) ? (($node instanceof \SimpleXMLElement) && count((array) $node)==0 ? null : $this->xml2Object($node)) : $node;
} else
$out->{$index} = (is_object($node) || is_array($node)) ? (($node instanceof \SimpleXMLElement) && count((array) $node)==0 ? null : $this->xml2Object($node)) : $node;
return
$out;
}
?>

函数结果如下所示
<?php
$xml
= simplexml_load_string('<?xml version="1.0" encoding="UTF-8" standalone="no"?><results><l1_elm1><l2_elm1>Some Text</l2_elm1><l2_elm2/></l1_elm1><l1_elm2><l2_elm1><l3_elm1>Array Index[0] - First property</l3_elm1><l3_elm2>Array Index[0] - Second property</l3_elm2><l3_elm3>Array Index[0] - Third property</l3_elm3></l2_elm1><l2_elm1><l3_elm1>Array Index[1] - First property</l3_elm1><l3_elm2>Array Index[1] - Second property</l3_elm2><l3_elm3>Array Index[1] - Third property</l3_elm3></l2_elm1></l1_elm2><l1_elm3/></results>');

var_dump( $this->xml2Object($xml) );

// var_dump xml2Object results
object(stdClass)#339 (3) {
["l1_elm1"]=>object(stdClass)#344 (2) {
["l2_elm1"]=>string(9) "Some Text"
["l2_elm2"]=>NULL
}
[
"l1_elm2"]=>object(stdClass)#347 (1) {
["l2_elm1"]=>array(2) {
[
0]=>object(stdClass)#348 (3) {
["l3_elm1"]=>string(31) "Array Index[0] - First property"
["l3_elm2"]=>string(32) "Array Index[0] - Second property"
["l3_elm3"]=>string(31) "Array Index[0] - Third property"
}
[
1]=>object(stdClass)#349 (3) {
["l3_elm1"]=>string(31) "Array Index[1] - First property"
["l3_elm2"]=>string(32) "Array Index[1] - Second property"
["l3_elm3"]=>string(31) "Array Index[1] - Third property"
}
}
}
[
"l1_elm3"]=>NULL
}

// VarDump Symphony xml2Object results something like
object (#345) {
+"l1_elm1": object (#339) {
+"l2_elm1": "Some Text"
+"l2_elm2": null
}
+
"l1_elm2": object (#347) {
+"l2_elm1": array(2) {
[
0] => object (#348) {
+"l3_elm1": "Array Index[0] - First property"
+"l3_elm2": "Array Index[0] - Second property"
+"l3_elm3": "Array Index[0] - Third property"
}
[
1] => object (#349) {
+"l3_elm1": "Array Index[1] - First property"
+"l3_elm2": "Array Index[1] - Second property"
+"l3_elm3": "Array Index[1] - Third property"
}
]
}
+
"l1_elm3": null
}
?>
0
thomas at guenneguez dot com
12 年前
仅使用 SimpleXML 合并两个 XML
如果注释只包含值,则函数已更正。

<?php
function mergeXML(&$base, $add)
{
if (
$add->count() != 0 )
$new = $base->addChild($add->getName());
else
$new = $base->addChild($add->getName(), $add);
foreach (
$add->attributes() as $a => $b)
{
$new->addAttribute($a, $b);
}
if (
$add->count() != 0 )
{
foreach (
$add->children() as $child)
{
mergeXML($new, $child);
}
}
}
?>

使用:<?php mergeXML($xmlElement, simplexml_load_string($toMerge)) ?>
0
philippe_marc_--a---t--_novartis_com
16 年前
提示:如果您在使用 SimpleXML 时遇到内存问题。
您可能需要使用 PHP>5.2.5 来避免这种情况:http://bugs.php.net/bug.php?id=38604
如果不可行,请避免使用“foreach ($xmldata->node as $node)”之类的调用。
0
php at werner dash ott dot de
17 年前
关于 SimpleXML 和会话

在会话上下文中创建 SimpleXML 对象(更准确地说,是 SimpleXMLElement 对象)并将其存储在 $_SESSION['XMLobject'] 中,此对象不会“存活”会话!

在重新进入会话时,print_r($_SESSION['XMLobject']) 会显示

['XMLobject'] => SimpleXMLElement Object
警告:节点在 /your_php_file.php 的第 xyz 行不再存在
(
)

(为了提高可读性,消息已简化。)
0
Jason Sheets <jsheets at shadonet dot com>
18 年前
这是我的 Simple XML 到数组函数,它是递归的,并且具有保持键值关系的好处,对我来说非常有效。

<?php
function XMLToArray($xml)
{
if (
$xml instanceof SimpleXMLElement) {
$children = $xml->children();
$return = null;
}

foreach (
$children as $element => $value) {
if (
$value instanceof SimpleXMLElement) {
$values = (array)$value->children();

if (
count($values) > 0) {
$return[$element] = XMLToArray($value);
} else {
if (!isset(
$return[$element])) {
$return[$element] = (string)$value;
} else {
if (!
is_array($return[$element])) {
$return[$element] = array($return[$element], (string)$value);
} else {
$return[$element][] = (string)$value;
}
}
}
}
}

if (
is_array($return)) {
return
$return;
} else {
return
$false;
}
}
?>
-2
Pyetro Costa [pyetrosafe at gmail dot com]
5 年前
这只是对 https://php.net/manual/en/ref.simplexml.php#112038 的函数进行的新的调整。

通过 is_array 进行检查,将转换提高到至少 3 级,但是空标签被转换为 SimpleXMLElement 类对象,添加了类型和大小检查,将这些空标签转换为 null。

查看示例
<?php
// 参考 https://php.net/manual/en/ref.simplexml.php#112038 中的函数
function xml2array($xmlObject, $out = array ()) {
foreach ((array)
$xmlObject as $index => $node )
$out[$index] = (is_object($node) || is_array($node)) ? xml2array($node) : $node;
return
$out;
}

$xml = simplexml_load_string('<?xml version="1.0" encoding="UTF-8" standalone="no"?><results><level1><l1_elm1><level2><l2_elm1>Some Text</l2_elm1><l2_elm2/></level2></l1_elm1><l1_elm2>Other String</l1_elm2><l1_elm3/></level1></results>');
$XML2Array = xml2array($xml);
var_dump($xml);
var_dump($XML2Array);

// 结果如下所示
// simplexml_load_string 结果
object(SimpleXMLElement)#227 (1) {
["level1"]=>object(SimpleXMLElement)#226 (3) {
["l1_elm1"]=>object(SimpleXMLElement)#236 (1) {
["level2"]=>object(SimpleXMLElement)#238 (2) {
["l2_elm1"]=>string(9) "Some Text"
["l2_elm2"]=>object(SimpleXMLElement)#239 (0) {}
}
}
[
"l1_elm2"]=>string(12) "Other String"
["l1_elm3"]=>object(SimpleXMLElement)#237 (0) {}
}
}

// xml2array 函数结果
array(1) {
[
"level1"]=>array(3) {
[
"l1_elm1"]=>array(1) {
[
"level2"]=>array(2) {
[
"l2_elm1"]=>string(9) "Some Text"
["l2_elm2"]=>array(0) {}
}
}
[
"l1_elm2"]=>string(12) "Other String"
["l1_elm3"]=>array(0) {}
}
}
?>

现在,检查节点类型和大小,如果节点是 SimpleXMLElement 实例并且计数为 0,则将值设置为 null(或者根据您的偏好设置为空字符串 "");
<?php
function xml2array($xmlObject, $out = array ()) {
foreach ((array)
$xmlObject as $index => $node )
$out[$index] = (is_object($node) || is_array($node)) ? (($node instanceof \SimpleXMLElement) && count((array) $node)==0 ? null : xml2array($node)) : $node;
return
$out;
}

$xml = simplexml_load_string('<?xml version="1.0" encoding="UTF-8" standalone="no"?><results><level1><l1_elm1><level2><l2_elm1>Some Text</l2_elm1><l2_elm2/></level2></l1_elm1><l1_elm2>Other String</l1_elm2><l1_elm3/></level1></results>');
var_dump(xml2array($xml));

// 现在结果如下所示
array(1) {
[
"level1"]=>array(3) {
[
"l1_elm1"]=>array(1) {
[
"level2"]=>array(2) {
[
"l2_elm1"]=>string(9) "Some Text"
["l2_elm2"]=>NULL
}
}
[
"l1_elm2"]=>string(12) "Other String"
["l1_elm3"]=>NULL
}
}
?>
-1
nathan at gimpstraw dot com
16 年前
我使用 SimpleXML 处理从 API 请求返回的数据,我遇到了 CDATA 问题以及从 HTML 实体获得的错误,这里是我想出的解决方案,不知道它是否是 最实用的,但它确实有效。

<?php
$str
= <<< XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<menu>
<item>
<title><![CDATA[Caf&eacute;]]></title>
<description><![CDATA[Some description.]]></description>
</item>
</menu>
XML;

$str = preg_replace("/\<\!\[CDATA\[(.*?)\]\]\>/ies", "'[CDATA]'.base64_encode('$1').'[/CDATA]'", $str);
$xml = new SimpleXMLElement($str);

// 返回项目标题
foreach ($xml->item as $item) {
$tmp = (string) $item->title;
$tmp = preg_replace("/\[CDATA\](.*?)\[\/CDATA\]/ies", "base64_decode('$1')", $tmp);
echo
$tmp;
}
?>
-1
Andrez zenarter at hotmail dot com
15 年前
我只想添加一个额外的内容
"将一个 SimpleXML 追加/组合/合并到另一个 SimpleXML"
父元素也应该具有属性。

<?php

function append_simplexml(&$simplexml_to, &$simplexml_from)
{

static
$firstLoop=true;

// 在这里向父元素添加属性
if( $firstLoop )
{
foreach(
$simplexml_from->attributes() as $attr_key => $attr_value )
{
$simplexml_to->addAttribute($attr_key, $attr_value);
}
}

foreach (
$simplexml_from->children() as $simplexml_child)
{
$simplexml_temp = $simplexml_to->addChild($simplexml_child->getName(), (string) $simplexml_child);
foreach (
$simplexml_child->attributes() as $attr_key => $attr_value)
{
$simplexml_temp->addAttribute($attr_key, $attr_value);
}

$firstLoop=false;

append_simplexml($simplexml_temp, $simplexml_child);
}

unset(
$firstLoop=false );
}

?>

我在将一个对象分配给一个稍后用作对象的变量时遇到了问题,然后我找到了上面的代码,它解决了我的问题的一半。我应该让它也具有父元素名称,但它没有。有更好的代码吗?
-1
codejunky32 at NOSPAM dot com
15 年前
只想添加一个关于如何从 SimpleXMLElement 中提取值的帖子。这并不像你想象的那样简单。因为它是一个复杂的对象,你不能直接访问元素。这是一个示例数据,代表了 SimpleXmlElement 的 var_dump。

array(1) {
[0]=>
object(SimpleXMLElement)#13 (2) {
["@attributes"]=>
array(1) {
["name"]=>
string(5) "title"
}
[0]=>
string(19) "PHP Tech Book"
}
}

如果你想提取书籍的标题,你需要将指定的元素强制转换为字符串,如下所示。
$newTitle = (string) $title[0];

假设您使用 `simplexml_load_string` 从 XML 文档中提取的 SimpleXMLElement 对象名为 `$title`。 为了从 XML 文档中最初访问 title 元素,您可以使用 xpath,如下所示。
$title = $doc->xpath('str[@name="title"]');

希望这能帮助到其他人。
-3
info at ajaxforum dot ru
15 年前
将一个 SimpleXML 对象追加/组合/合并到另一个 SimpleXML 对象

<?php
include 'example.php';
$el1 = new SimpleXMLElement($xmlstr);
$el2 = new SimpleXMLElement($xmlstr);

// 错误的方法!
// PHP 会将 $el2->movie[0] 默默地转换为字符串
$el1->addChild('movie', $el2->movie[0]);

// 错误的方法!
// PHP 5.1 会将 $el2->movie[0] 转换为字符串并生成警告:无法将复杂类型分配给属性。无法将复杂类型分配给节点
// PHP 5.2 会将 $el2->movie[0] 默默地转换为字符串
$el1->addChild('movie');
$el1->movie[2] = $el2->movie[0];

// 正确的方法!
$el1_movie = $el1->addChild('movie');
append_simplexml($el1_movie, $el2->movie[0]);

echo
"<pre>"; print_r($el1); echo "</pre>";

/**
* 将一个 SimpleXML 对象追加到另一个 SimpleXML 对象
*
* @param object $simplexml_to
* @param object $simplexml_from
* @author Boris Korobkov
* @link http://www.ajaxforum.ru/
*/
function append_simplexml(&$simplexml_to, &$simplexml_from)
{
foreach (
$simplexml_from->children() as $simplexml_child)
{
$simplexml_temp = $simplexml_to->addChild($simplexml_child->getName(), (string) $simplexml_child);
foreach (
$simplexml_child->attributes() as $attr_key => $attr_value)
{
$simplexml_temp->addAttribute($attr_key, $attr_value);
}

append_simplexml($simplexml_temp, $simplexml_child);
}
}
?>
To Top