打印数组时 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_dumpvar_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