如何将DOMNodeList对象转换为数组

26

我有这段代码:

     $dom = new DOMDocument();
     $dom->load('file.xml');
     $names = $dom->getElementsByTagName('name');

现在,$names 是一个 DOMNodeList 对象,我需要将它转换为一个数组。

     $names = (array)$names;
     var_dump($names);  // empty array

上述代码无法正常运行,并返回一个空数组,为什么?

5个回答

83

使用iterator_to_array()函数将DomNodeList转换为数组

$document = new DomDocument();
$document->load('test.xrds');
$nodeList = $document->getElementsByTagName('Type');
$array = iterator_to_array($nodeList);

3
这应该是正确的答案。它有效且非常简单易懂。 - CJ Dennis
同意。这是最好的。 - dev_willis
1
这对我不起作用。Catchable fatal error: Argument 1 passed to iterator_to_array() must implement interface Traversable, instance of DOMNodeList given - Byron Whitlock
1
就我所阅读的文档(5.6.35),DOMNodeList 实现了 Traversable。文档中的变更日志没有提到这个改变是何时发生的。我也没有尝试过这个特定的解决方案,可能还存在其他的 bug。 - Stephan Samuel

6
因为 (array) 不适用于 DOMNodeList 对象,因为 length 是一个整数类型的属性。如果将对象转换为数组,则结果是一个数组,其元素是对象的属性。键是成员变量名称,有一些例外情况:无法访问整数属性;私有变量在变量名之前附加了类名;受保护的变量在变量名之前附加了 '*'。这些附加值两侧有空字节。由于 DOMNodeList 实现了 Traversable 接口,因此您可以很容易地自己创建数组。
$array = array();
foreach($names as $node){
    $array[] = $node;
}

编辑:我已经删除了最初的解释,因为它在这里不适用。手册的意思是具有数字名称的属性被传递到数组中,但不能读取:

<?php

class Foo{
    public function __construct(){
        $this->{123} = 456;
    }
}

$array = (array)new Foo;
var_dump($array);
var_dump($array['123']);

array(1) {
  ["123"]=>
  int(456)
}

Notice: Undefined offset: 123 in D:\tmp\borrame.php on line 11
NULL

解释可能更多地是基于 DOMNodeList 不是由 PHP 代码创建的用户对象,而是在 C 中定义的内置对象,因此适用不同的规则。

4
只需遍历元素并将它们放入数组中即可:
$names_array = array();
foreach ($names as $name) {
    $names_array[] = $name; // this is a DOMNode instance
    // you might want to have the textContent of them like this
    $names_array[] = $name->textContent;
}

这样它们仍然是DOMNode实例,你可能想要获取它们的textContent属性。


2
假设您需要实际值而不是创建DOM节点数组:
foreach($nodelist as $node) {
    $values[] = $node->nodeValue;
}

1
$dom = new DOMDocument();
$dom->load('file.xml');
$names = $dom->getElementsByTagName('name');
$headlines = array();

foreach($names as $name) {
    $headline = array();
    if($name->childNodes->length) {
        foreach($name->childNodes as $i) {
            $headline[$i->nodeName] = $i->nodeValue;
        }
    }

    $headlines[] = $headline;
} 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接