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 則註釋

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);
}

}
?>
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++)

我費了好大勁才搞清楚這一點……
brack at wjp dot de
16 年前
在 PHP 5.2.5 (Windows) 中,無法使用 foreach 正確迭代 DOMNode->childNodes 返回的 DOMNodeList 物件。我必須使用 for 迴圈搭配 DOMNodeList 的 item() 方法才能正確迭代所有子節點。

我不知道這算不算是一個 bug,但顯然它就是。
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;
}
}
drichter at muvicom dot de
16 年前
我做了一些測試,發現了 2 個結果
(我的系統:Windows XP,PHP 5.2.1)

1) 如果您只使用 foreach 進行唯讀操作或少量屬性寫入,那麼如同 "james dot j dot hackett at gmail dot com" 所述,使用 foreach 迭代是正常運作的。

2) 如果您在迭代時執行一些 DOM 操作,foreach 就會無法正常運作。在我的情況下,是將迭代的 $node 作為子節點添加到一個新節點

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

這樣只會得到第一個元素……

我將其解釋為一種令人困惑但正確的行為,因為在將節點附加到其他位置時,$dom 物件內部發生了變化……

因此,如果您想執行類似 2) 的操作,請使用 for、length 和 item() :)
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 尚未針對此類別實作 */

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

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

</code>

希望這有幫助。
james dot j dot hackett at gmail dot com
16 年前
回覆 'kassah at gmail'

您不需要將 DOMNodeList 轉換為陣列即可使用 'foreach' 進行迭代。您可以直接將 foreach 與 DOMNodeList 一起使用。

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

foreach ($nodeList as $node) {
echo $node->nodeValue;
}
bobvandell at hotmail dot com
16 年前
這樣說其實不正確。您可以將函式結果作為物件使用。這讓構建資料庫的 API 變得非常簡潔俐落。例如:

我們的程式碼

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

我們使用上面的程式碼來獲取與特定標籤連結的資源所連結的文章。
drichter at muvicom dot de
16 年前
補充我的第一個註記

傳統的 for 迴圈不允許您在迴圈時更改 DOM 樹狀結構 - 其效果與 foreach 幾乎相同。因此,您必須將節點收集到一個陣列中,並在第二個迴圈(這次迴圈該陣列...)中執行樹狀結構更改操作。
To Top