DOMNodelist::item
(PHP 5, PHP 7, PHP 8)
DOMNodelist::item — インデックスで指定したノードを取得する
説明
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
+add a note
User Contributed Notes 9 notes
vinyanov at poczta dot onet dot pl ¶
16 years ago
SimpleXML has its own SPL iterator. See http://www.php.net/~helly/php/ext/spl/classSimpleXMLIterator.html . But I guess that there are none for DOM nodes. By the way, two out of three implementations I found over the Net were not recursive, so I wrote my own. Here is the snippet:
<?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);
}
}
?>
Remember to use RecursiveIteratorIterator::SELF_FIRST flag when you create your iterator iterator.
<?php
$iterator = new DOMNodeListIterator($document -> childNodes);
$iterator = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST);
?>
Should work, has just few minutes though. :)
Geoffrey Thubron ¶
17 years ago
@ tfg_allardyce at gmail dot com
You could loop through the list backwards, that way, you are only ever taking off the last item from the list, and hence wont have disrupted the order.
Anonymous ¶
12 years ago
calling domnodelist->item($i) with an index $i greater than domnodelist->length - 1 , will return the entire document, will not produce an error, and will not circle back to the start of the list.
Nagy Attila ¶
13 years ago
DOMNodeList::item does not return in constant time!
If you need to iterate over large nodelist then you'd better use standard navigation.
Instead of:
<?php
foreach ($nodelist as $node) {
// do something
}
?>
you could do:
<?php
$node = $parentnode->firstChild;
do {
// do something
} while ($node = $node->nextSibling);
?>
jeffpuckett2 at gmail dot com ¶
8 years ago
DOMNodelist::item can return a DOMElement object, which extends DOMNode class. But it can also return a DOMText object.
<?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;
?>
Results in this output:
DOMText
DOMElement
DOMText
DOMElement
DOMText
DOMElement
DOMText
DOMElement
DOMText
Hayley Watson ¶
17 years ago
Keep in mind that DOMNodelists are "live" - changes to the document or node that the DOMNodelist was derived from will be reflected in the DOMNodelist. In other words, a list of a parent node's children will change if you change the parent's children!
olivier dot berger at it-sudparis dot eu ¶
16 years ago
It seems that with zend.ze1_compatibility_mode on, the only way to iterate over the items list is with :
for ($i = 0; $i < $nodeList->length; ++$i) {
$nodeName = $nodeList->item($i)->nodeName;
$nodeValue = $nodeList->item($i)->nodeValue;
}
As other attemps failed :
for ($i = 0; $i < $nodeList->length; ++$i) {
$node = &$nodeList->item($i);
$nodeName = $node->nodeName;
$nodeValue = $node->nodeValue;
}
or :
foreach ($nodeList as $node) {
echo $node->nodeName;
echo $node->nodeValue;
}
james dot dunmore at gmai dot com ¶
17 years ago
tfg_allardyce at gmail dot com
I have had exactly this problem.
To rectify I've had to do this:
<?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);
}
?>
Rather than this:
(which I will bug report)
<?php
$old_element = $doc->getElementsByTagName('Element1')->item(0):
$new_element = $doc->createElement('NewElement1');
foreach($old_element->childNode as $node)
{
$new_element->appendChild($node);
}
?>
Using the latter, randomally removes the children!
oliver dot christen at camptocamp dot com ¶
17 years ago
NodeList are something annoying because you can't output the content with a simple print_r, so I did a little function that add all the node to a new empty DOMDocument and output it as a string.
Have fun.
<?php
public function domNodeList_to_string($DomNodeList) {
$output = '';
$doc = new DOMDocument;
while ( $node = $DomNodeList->item($i) ) {
// import node
$domNode = $doc->importNode($node, true);
// append node
$doc->appendChild($domNode);
$i++;
}
$output = $doc->saveXML();
$output = print_r($output, 1);
// I added this because xml output and ajax do not like each others
$output = htmlspecialchars($output);
return $output;
}
?>
↑ and ↓ to navigate •
Enter to select •
Esc to close
Press Enter without
selection to search using Google