PHP Conference Japan 2024

DOMNodeList 类

(PHP 5, PHP 7, PHP 8)

类概要

class DOMNodeList implements IteratorAggregate, Countable {
/* 属性 */
public readonly int $length;
/* 方法 */
public count(): int
}

属性

length

列表中节点的数量。有效子节点索引的范围是0到length - 1(包含)。

变更日志

版本 描述
8.0.0 DOMNodeList 现在实现了 IteratorAggregate。之前实现了 Traversable
7.2.0 实现了 Countable 接口,并返回 length 属性的值。

备注

注意: 可以使用数组语法访问列表中的节点。

目录

添加注释

用户贡献的注释 9 条注释

26
ignitedfirestarter at gmail dot com
12 年前
如果您想递归遍历 DOM,这可能会有所帮助
<?php

/**
* PHP 的 DOM 类是递归的,但没有提供 RecursiveIterator 的实现。
* 此类为遍历 DOMNodeList 提供了一个 RecursiveIterator
*/
class DOMNodeRecursiveIterator extends ArrayIterator implements RecursiveIterator {

public function
__construct (DOMNodeList $node_list) {

$nodes = array();
foreach(
$node_list as $node) {
$nodes[] = $node;
}

parent::__construct($nodes);

}

public function
getRecursiveIterator(){
return new
RecursiveIteratorIterator($this, RecursiveIteratorIterator::SELF_FIRST);
}

public function
hasChildren () {
return
$this->current()->hasChildNodes();
}


public function
getChildren () {
return new
self($this->current()->childNodes);
}

}
?>
13
geompse at gmail dot com
14 年前
请注意,$length 是计算出来的 (php5.3.2)。
迭代大型 NodeList 可能非常耗时。

建议使用
$nb = $nodelist->length;
for($pos=0; $pos<$nb; $pos++)

而不是
for($pos=0; $pos<$nodelist->length; $pos++)

我很难弄清楚这一点……
11
brack at wjp dot de
16 年前
在 PHP 5.2.5 (Windows) 中,无法使用 foreach 正确迭代 DOMNode->childNodes 返回的 DOMNodeList 对象。相反,我必须结合使用 for 循环和 DOMNodeList 的 item() 方法才能正确迭代所有子节点。

我不知道这是否真的是一个错误,但显然它就是这样。
14
c dot 1 at smithies dot org
16 年前
如果反向迭代,您可以修改甚至删除 DOMNodeList 中的节点

$els = $document->getElementsByTagName('input');
for ($i = $els->length; --$i >= 0; ) {
$el = $els->item($i);
switch ($el->getAttribute('name')) {
case 'MAX_FILE_SIZE'
$el->parentNode->removeChild($el);
break;
case 'inputfile'
$el->setAttribute('type', 'text');
//break;
}
}
11
drichter at muvicom dot de
16 年前
我做了一些测试,并发现了两个结果
(我的系统:安装了 PHP 5.2.1 的 Win XP)

1) 如果您只对 foreach 进行只读操作或对某些属性进行少量写入,则使用 foreach 进行迭代确实可以正常工作,正如 "james dot j dot hackett at gmail dot com" 所写的那样。

2) 如果您在迭代时进行一些 DOM 操作,则 foreach 无法工作。在我的情况下,它是在将迭代的 $node 作为子节点添加到新节点。

$newNode = $dom->createElement('newNode') ;
foreach ($nodeList as $node) {
echo $node->nodeValue ;
$newNode->appendChild($node) ;
}

这只会给你第一个元素……

我将其解释为一种令人困惑但正确的行为,因为在将节点添加到另一个位置时,$dom 对象内部发生了更改……

因此,如果您想执行类似 2) 的操作,请使用 for、length 和 item() :)
3
niko at yopmail dot com
3 年前
值得一提的是,DOMNodeList 不是数组,因此您必须先将其转换为数组,然后才能使用 for、foreach 或 array_map、array_filter、array_walk 函数。

使用 iterator_to_array 进行转换 (自 PHP 5.1.0 起)。

<code>
/* @ suppress warning var_dump not yet implemented for class */

@array_walk( iterator_to_array( $Some_NodeList ), 'var_dump' ) );

foreach( iterator_to_array( $Some_NodeList ) as $node )
@var_dump( $node );

</code>

希望对您有所帮助。
6
james dot j dot hackett at gmail dot com
16 年前
回复 'kassah at gmail'

您无需将 DOMNodeList 转换为数组即可使用 'foreach' 遍历它。您可以直接使用 DOMNodeList 和 foreach。

$nodeList = $someDomDocument->getElementsbytagname('user');

foreach ($nodeList as $node) {
echo $node->nodeValue;
}
1
bobvandell at hotmail dot com
16 年前
这实际上是不正确的。您可以使用函数结果作为对象。它使构建数据库的 API 非常简洁明了。例如

我们的代码

$articles = Node::screate('tags', 123456)->assets('like:title:test')->articles;

我们使用上述代码来获取链接到资产(链接到我们数据库中的特定标签)的文章。
-2
drichter at muvicom dot de
16 年前
补充我的第一条注释

传统的for循环不允许你在循环过程中修改DOM树——其效果与foreach几乎相同。因此,你必须将节点收集到一个数组中,然后在一个第二个循环中(这次循环遍历数组……)进行树的修改操作。
To Top