DOMNodeList::item

(PHP 5, PHP 7, PHP 8)

DOMNodeList::item检索由索引指定的节点

描述

public DOMNodeList::item(int $index): DOMElement|DOMNode|DOMNameSpaceNode|null

检索 DOMNodeList 对象中由 index 指定的节点。

提示

如果您需要知道集合中的节点数量,请使用 DOMNodeList 对象的 length 属性。

参数

index

集合中节点的索引。

返回值

DOMNodeListindex 位置的节点,或者如果该索引无效,则为 null

范例

示例 #1 遍历表格中的所有条目

<?php

$doc
= new DOMDocument;
$doc->load('book.xml');

$items = $doc->getElementsByTagName('entry');

for (
$i = 0; $i < $items->length; $i++) {
echo
$items->item($i)->nodeValue . "\n";
}

?>

或者,您可以使用 foreach,这是一种更便捷的方式

<?php

foreach ($items as $item) {
echo
$item->nodeValue . "\n";
}

?>

上面的示例将输出

Title
Author
Language
ISBN
The Grapes of Wrath
John Steinbeck
en
0140186409
The Pearl
John Steinbeck
en
014017737X
Samarcande
Amine Maalouf
fr
2253051209

添加注释

用户贡献注释 9 个注释

3
vinyanov at poczta dot onet dot pl
16 年前
SimpleXML 有自己的 SPL 迭代器。查看 https://php.net/~helly/php/ext/spl/classSimpleXMLIterator.html 。但我认为 DOM 节点没有。顺便说一句,我发现的三个实现中有两个不是递归的,所以我写了自己的。以下是代码片段

<?php

class DOMNodeListIterator implements RecursiveIterator
{
private
$nodes,
$offset;

function
__construct(DOMNodeList $nodes)
{
return
$this -> nodes = $nodes;
}

function
rewind()
{
return
$this -> offset = 0;
}

function
current()
{
return
$this -> nodes -> item($this -> offset);
}

function
key()
{
return
$this -> current() -> nodeName;
}

function
next()
{
return
$this -> offset++;
}

function
valid()
{
return
$this -> offset < $this -> nodes -> length;
}

function
hasChildren()
{
return isset(
$this -> current() -> childNodes -> length) && $this -> current() -> childNodes -> length > 0;
}

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

?>

记住,在创建迭代器迭代器时使用 RecursiveIteratorIterator::SELF_FIRST 标志。

<?php

$iterator
= new DOMNodeListIterator($document -> childNodes);
$iterator = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST);

?>

应该可以工作,不过也就几分钟时间。:)
3
Geoffrey Thubron
17 年前
@ tfg_allardyce at gmail dot com

您可以从后向前循环遍历列表,这样,您就只从列表中删除最后一个项目,因此不会破坏顺序。
4
匿名
12 年前
使用大于 domnodelist->length - 1 的索引 $i 调用 domnodelist->item($i) 将返回整个文档,不会产生错误,也不会循环回到列表的开头。
4
Nagy Attila
13 年前
DOMNodeList::item 的时间复杂度不是常数!

如果您需要遍历大型节点列表,最好使用标准导航。

而不是

<?php
foreach ($nodelist as $node) {
// 做一些事
}
?>

你可以这样做

<?php
$node
= $parentnode->firstChild;

do {
// 做一些事
} while ($node = $node->nextSibling);
?>
1
jeffpuckett2 at gmail dot com
8 年前
DOMNodelist::item 可以返回 DOMElement 对象,它扩展了 DOMNode 类。但它也可以返回 DOMText 对象。

<?php
$xml
= '
<root>
<node/>
<node>
<sub>more</sub>
</node>
<node>
<sub>another</sub>
</node>
<node>value</node>
</root>
'
;

$doc = new DOMDocument();
$doc->loadXML($xml);

$items = $doc->documentElement->childNodes;
for (
$i = 0; $i < $items->length; $i++)
echo
get_class($items->item($i)).PHP_EOL;
?>

结果为以下输出

DOMText
DOMElement
DOMText
DOMElement
DOMText
DOMElement
DOMText
DOMElement
DOMText
1
Hayley Watson
16 年前
请记住,DOMNodelists 是“动态的” - 对文档或 DOMNodelist 来源节点的更改将反映在 DOMNodelist 中。换句话说,如果您更改了父节点的子节点,则父节点子节点的列表也会更改!
0
olivier dot berger at it-sudparis dot eu
15 年前
似乎在 zend.ze1_compatibility_mode 启用时,遍历 items 列表的唯一方法是
for ($i = 0; $i < $nodeList->length; ++$i) {
$nodeName = $nodeList->item($i)->nodeName;
$nodeValue = $nodeList->item($i)->nodeValue;
}

其他尝试都失败了

for ($i = 0; $i < $nodeList->length; ++$i) {
$node = &$nodeList->item($i);
$nodeName = $node->nodeName;
$nodeValue = $node->nodeValue;
}

或者
foreach ($nodeList as $node) {
echo $node->nodeName;
echo $node->nodeValue;
}
0
james dot dunmore at gmai dot com
17 年前
tfg_allardyce at gmail dot com

我遇到了完全相同的问题。

为了纠正这个问题,我不得不这样做
<?php
$old_element
= $doc->getElementsByTagName('Element1')->item(0);
$new_element = $doc->createElement('NewElement1');

$old_element_childNodes = $old_element->childNodes;
$length = $old_element_childNodes->length;

for(
$i = 0; $i < $length; $i++)
{
$oldChildren_array[] = $old_element_childNodes->item($i);
}

foreach(
$oldChildren_array as $old_c)
{
$new_element->appendChild($old_c);
}
?>

而不是这个
(我会提交错误报告)
<?php
$old_element
= $doc->getElementsByTagName('Element1')->item(0):
$new_element = $doc->createElement('NewElement1');

foreach(
$old_element->childNode as $node)
{
$new_element->appendChild($node);
}

?>

使用后者,会随机删除子节点!
-1
oliver dot christen at camptocamp dot com
17 年前
NodeList 非常令人讨厌,因为您无法使用简单的 print_r 输出内容,所以我写了一个小函数,将所有节点添加到一个新的空 DOMDocument 并将其输出为字符串。
玩得开心。

<?php

public function domNodeList_to_string($DomNodeList) {
$output = '';
$doc = new DOMDocument;
while (
$node = $DomNodeList->item($i) ) {
// 导入节点
$domNode = $doc->importNode($node, true);
// 追加节点
$doc->appendChild($domNode);
$i++;
}
$output = $doc->saveXML();
$output = print_r($output, 1);
// 我添加了这个,因为 xml 输出和 ajax 不喜欢彼此
$output = htmlspecialchars($output);
return
$output;
}

?>
To Top