打印数组时 SimpleXMLElement 对象中的奇怪行为
Weird behaviour in SimpleXMLElement Object when printing the array
我正在努力处理 SimpleXMLElement Object
中的数组。当我打印数组 $node->reference
.
时,我以某种方式没有得到预期的结果
print_r($node);
显示:
SimpleXMLElement Object
(
[reference] => Array
(
[0] => SimpleXMLElement Object
(
[@attributes] => Array
(
[resourceIdentifier] => 52chgb7f-1a00-4eaf-ac8a-5d4557f9796a
)
)
[1] => SimpleXMLElement Object
(
[@attributes] => Array
(
[resourceIdentifier] => 52cbccc3-b754-4e88-9238-5d5257f9796a
)
)
)
)
但是print_r($node->reference);
和print_r($node->reference->children());
显示:
SimpleXMLElement Object
(
[@attributes] => Array
(
[resourceIdentifier] => 52chgb7f-1a00-4eaf-ac8a-5d4557f9796a
)
)
我希望看到:
Array
(
[0] => SimpleXMLElement Object
(
[@attributes] => Array
(
[resourceIdentifier] => 52chgb7f-1a00-4eaf-ac8a-5d4557f9796a
)
)
[1] => SimpleXMLElement Object
(
[@attributes] => Array
(
[resourceIdentifier] => 52cbccc3-b754-4e88-9238-5d5257f9796a
)
)
)
编辑
这里是一些要重现的代码:
<?php
$xml = '<?xml version="1.0" encoding="UTF-8" ?>
<items>
<item>
<reference resourceIdentifier="52chgb7f-1a00-4eaf-ac8a-5d4557f9796a" />
<reference resourceIdentifier="52cbccc3-b754-4e88-9238-5d5257f9796a" />
</item>
<item>
<reference resourceIdentifier="52chgb7f-1a00-4eaf-ac8a-5d4557f9796a" />
</item>
<item>
<reference resourceIdentifier="52chgb7f-1a00-4eaf-ac8a-5d4557f9796a" />
<reference resourceIdentifier="52chgb7f-1a00-4eaf-ac8a-5d4557f9796a" />
<reference resourceIdentifier="52cbccc3-b754-4e88-9238-5d5257f9796a" />
</item>
</items>';
$items = new \SimpleXMLElement($xml);
foreach ($items as $item) {
echo '<h1>Item</h1>';
echo '<pre>';
print_r($item);
print_r($item->reference); // Returns always 1 SimpleXMLElement Object?
print_r($item->reference->children()); // Returns always 1 SimpleXMLElement Object?
echo '</pre>';
}
简单的答案是:不要依赖 print_r
。 SimpleXML 的问题在于它大量使用了 "magic" 和 print_r
(以及 var_dump
、var_export
和几乎任何其他通用调试或序列化函数)不会向您展示它的行为方式。此外,这非常重要,a SimpleXMLElement 不包含任何数组。
我写了 a dedicated debug function,它虽然不完美,但在通过 SimpleXML objects 进行递归方面比原生的做得更好。
此特定行为的原因是您可以使用 $node->reference
来引用 或者 所有 children 的列表称为 reference
、或第一个这样的child。以下都是等价的:
// Access as iterable list
foreach ( $node->reference as $ref ) {
echo $ref['resourceIdentifier'];
// only loop once
break;
}
// Access as numerically indexed array
echo $node->reference[0]['resourceIdentifier'];
// Access first item by default
echo $node->reference['resourceIdentifier'];
当您有一个 "deep but narrow" 的文档时,这非常方便,例如
$xml = simplexml_load_string('<foo><bar><baz><quux hello="world" /></baz></bar></foo>');
echo $xml->bar->baz->quux['hello']; // world
您不必检查节点是唯一的还是多个,SimpleXML 只允许您编写这样的表达式并忽略任何倍数:
$xml = simplexml_load_string('<foo><bar><baz><quux hello="world" /><quux ignored="true" /></baz></bar><bar>ignored</bar></foo>');
echo $xml->bar->baz->quux['hello']; // world
我正在努力处理 SimpleXMLElement Object
中的数组。当我打印数组 $node->reference
.
print_r($node);
显示:
SimpleXMLElement Object
(
[reference] => Array
(
[0] => SimpleXMLElement Object
(
[@attributes] => Array
(
[resourceIdentifier] => 52chgb7f-1a00-4eaf-ac8a-5d4557f9796a
)
)
[1] => SimpleXMLElement Object
(
[@attributes] => Array
(
[resourceIdentifier] => 52cbccc3-b754-4e88-9238-5d5257f9796a
)
)
)
)
但是print_r($node->reference);
和print_r($node->reference->children());
显示:
SimpleXMLElement Object
(
[@attributes] => Array
(
[resourceIdentifier] => 52chgb7f-1a00-4eaf-ac8a-5d4557f9796a
)
)
我希望看到:
Array
(
[0] => SimpleXMLElement Object
(
[@attributes] => Array
(
[resourceIdentifier] => 52chgb7f-1a00-4eaf-ac8a-5d4557f9796a
)
)
[1] => SimpleXMLElement Object
(
[@attributes] => Array
(
[resourceIdentifier] => 52cbccc3-b754-4e88-9238-5d5257f9796a
)
)
)
编辑
这里是一些要重现的代码:
<?php
$xml = '<?xml version="1.0" encoding="UTF-8" ?>
<items>
<item>
<reference resourceIdentifier="52chgb7f-1a00-4eaf-ac8a-5d4557f9796a" />
<reference resourceIdentifier="52cbccc3-b754-4e88-9238-5d5257f9796a" />
</item>
<item>
<reference resourceIdentifier="52chgb7f-1a00-4eaf-ac8a-5d4557f9796a" />
</item>
<item>
<reference resourceIdentifier="52chgb7f-1a00-4eaf-ac8a-5d4557f9796a" />
<reference resourceIdentifier="52chgb7f-1a00-4eaf-ac8a-5d4557f9796a" />
<reference resourceIdentifier="52cbccc3-b754-4e88-9238-5d5257f9796a" />
</item>
</items>';
$items = new \SimpleXMLElement($xml);
foreach ($items as $item) {
echo '<h1>Item</h1>';
echo '<pre>';
print_r($item);
print_r($item->reference); // Returns always 1 SimpleXMLElement Object?
print_r($item->reference->children()); // Returns always 1 SimpleXMLElement Object?
echo '</pre>';
}
简单的答案是:不要依赖 print_r
。 SimpleXML 的问题在于它大量使用了 "magic" 和 print_r
(以及 var_dump
、var_export
和几乎任何其他通用调试或序列化函数)不会向您展示它的行为方式。此外,这非常重要,a SimpleXMLElement 不包含任何数组。
我写了 a dedicated debug function,它虽然不完美,但在通过 SimpleXML objects 进行递归方面比原生的做得更好。
此特定行为的原因是您可以使用 $node->reference
来引用 或者 所有 children 的列表称为 reference
、或第一个这样的child。以下都是等价的:
// Access as iterable list
foreach ( $node->reference as $ref ) {
echo $ref['resourceIdentifier'];
// only loop once
break;
}
// Access as numerically indexed array
echo $node->reference[0]['resourceIdentifier'];
// Access first item by default
echo $node->reference['resourceIdentifier'];
当您有一个 "deep but narrow" 的文档时,这非常方便,例如
$xml = simplexml_load_string('<foo><bar><baz><quux hello="world" /></baz></bar></foo>');
echo $xml->bar->baz->quux['hello']; // world
您不必检查节点是唯一的还是多个,SimpleXML 只允许您编写这样的表达式并忽略任何倍数:
$xml = simplexml_load_string('<foo><bar><baz><quux hello="world" /><quux ignored="true" /></baz></bar><bar>ignored</bar></foo>');
echo $xml->bar->baz->quux['hello']; // world