如何获取simplexml对象的所有元素

时间:2013-06-07 18:55:55

标签: php simplexml

好吧,我完全被这里难过了。我发现了类似的问题,但答案似乎不适用于我的具体问题。我已经开始和关闭了好几天。

我在这里有这个simplexml对象(它实际上比这更长,很多,但是我正在删除所有无关的东西,所以你实际上会看到它):

SimpleXMLElement Object
(
    [SubjectClassification] => Array
        (
            [0] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [Authority] => Category Code
                            [Value] => s
                            [Id] => s
                        )

                )

            [1] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [Authority] => Subject
                            [Value] => Sports
                            [Id] => 54df6c687df7100483dedf092526b43e
                        )

                )

            [2] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [Authority] => Subject
                            [Value] => Professional baseball
                            [Id] => 20dd2c287e4e100488e5d0913b2d075c
                        )

                )

        )

)

我通过对包含以下内容的变量执行print_r来获取此代码块:

$subjects->SubjectClassification->children();

现在,我想了解subjectClassification数组的所有元素。他们都是!但是当我这样做时:

$subjects->SubjectClassification;

或者这个:

$subjects->SubjectClassification->children();

如果我尝试通过循环获取所有数组元素,我得到的就是:

SimpleXMLElement Object
(
    [@attributes] => Array
        (
            [Authority] => Category Code
            [Value] => s
            [Id] => s
        )

)

为什么呢?我怎样才能得到一切?

5 个答案:

答案 0 :(得分:1)

您可以使用xpath执行此操作。它是我找到的最简单的方法和最有效的方法,并减少了对大量for循环的需求,以及解决项目的问题。要获得所需的所有节点,您可以使用:

如果你的xml是这样的:

<Subjects>
<SubjectClassification>
</SubjectClassification>
<SubjectClassification>
</SubjectClassification>
<SubjectClassification>
</SubjectClassification>
</Subjects>

然后,要获得数组中的所有主题分类,您可以执行以下操作:

$subject_classifications = $xml->xpath("//SubjectClassification");

xml变量引用主simplexml对象,即使用simplexml加载的文件。

然后你可以使用像这样的foreach循环遍历数组:

foreach($subject_classifications as $subject_classification){
echo (string) $subject_classification->Authority;
echo (string) $subject_classification->Value;
echo (string) $subject_classification->Id;
}

您的结构可能会有所不同,但无论如何您都会想到这个主意。你可以在这里看到一篇来自IBM的好文章"Using Xpath With PHP"

答案 1 :(得分:1)

由于SimpleXML在多大程度上重载了PHP语法,依靠print_r来确定SimpleXML对象中的内容,或者你可以用它做什么,并不总是有用。 (我写的a couple of debugging functions旨在更全面。)最后,引用应该是XML结构本身,以及SimpleXML如何工作的知识。

在这种情况下,它从您提供的输出中看出,您拥有的是所有称为SubjectClassification的元素列表,以及彼此之间的所有兄弟。因此,您不希望调用$subjects->SubjectClassification->children(),因为这些节点没有子节点。

如果没有更好地了解基础XML结构,很难说更多,所以我暂时保存这个不完整的答案。

答案 2 :(得分:1)

对于<subjectClassification> s的所有后代(即儿童,孙子,曾孙子,盛大......(你明白了)) “所有元素[...]所有元素!”当你命名它时),你可以使用支持更高级查询的Xpath(至少我认为你就是这样)正在寻找,你的问题没有给出任何详细的描述,也没有给出你明确的“all”的例子。

对于SimpleXML,您只能使用Xpath查询元素(和属性),但由于您只需要元素,因此这不是显示停止:

$allOfThem = $subjects->xpath('./SubjectClassification//*');

这里的关键点是Xpath表达式:

./SubjectClassification//*

根据开头的点.,它相对于context-node,在您的情况下为$subjects。然后查找下降到名为 SubjectClassification 的直接子元素的所有元素。这适用于//(未指定的深度)和*(任何元素,星形充当通配符)。

所以希望这可以在几个月后回答你的问题。我只是通过清理一些XML问题来偶然发现它,也许这对将来的参考也很有用。

答案 3 :(得分:0)

我已经添加了第二个答案,以防万一实际上抛出的是检索属性数组而不是节点。这就是如何打印主$ xml对象中每个SubjectClassification的属性。

foreach($xml->SubjectClassification->attributes() as $key => $value) {
    echo $key . " : " . $value "\n";
}

答案 4 :(得分:0)

我发现count会返回正确数量的元素,然后您可以使用标准for循环来迭代它们:

$n = count($subjects->SubjectClassification);
for ($i = 0; $i < $n; $i++) {
    var_dump($subjects->SubjectClassification[$i]);
}

我不确定为什么foreach循环不起作用,也不知道为什么直接转储$subjects->SubjectClassification只显示第一个节点,但对于任何偶然发现这个古老问题的人来说,以上是一种无需借助外部库即可查找更多信息的方法。