PHP Conference Japan 2024

DOMNodeList::item

(PHP 5, PHP 7, PHP 8)

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

描述

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

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

提示

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

参数

index

节点在集合中的索引。

返回值

DOMNodeList 中位于 index 位置的节点,如果该索引无效则返回 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";
}

?>

示例 #2 使用数组语法访问项目

<?php

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

?>

示例 #3 使用 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 条注释

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

?>

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

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

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

而不是

<?php
foreach ($nodelist as $node) {
// 执行某些操作
}
?>

您可以这样做

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

do {
// 执行某些操作
} while ($node = $node->nextSibling);
?>
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
Hayley Watson
17年前
请记住,DOMNodelists 是“动态的” - 对文档或 DOMNodelist 派生自的节点所做的更改将反映在 DOMNodelist 中。换句话说,如果更改父节点的子节点,则父节点子节点的列表将发生更改!
olivier dot berger at it-sudparis dot eu
16 年前
似乎在 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;
}
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);
}

?>

使用后者,会随机删除子节点!
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