PHP: DOMNodeList - Manual (original) (raw)
The DOMNodeList class
(PHP 5, PHP 7, PHP 8)
Introduction
Represents a live list of nodes.
Class synopsis
Properties
length
The number of nodes in the list. The range of valid child node indices is 0 to length - 1 inclusive.
Changelog
| Version | Description |
|---|---|
| 8.0.0 | DOMNodeList implementsIteratorAggregate now. Previously, Traversable was implemented instead. |
| 7.2.0 | The Countable interface is implemented and returns the value of the length property. |
Notes
Note: Nodes in the list can be accessed by array syntax.
Table of Contents
- DOMNodeList::count — Get number of nodes in the list
- DOMNodeList::getIterator — Retrieve an external iterator
- DOMNodeList::item — Retrieves a node specified by index
Found A Problem?
ignitedfirestarter at gmail dot com ¶
13 years ago
If you want to recurse over a DOM then this might help:
<?php
/**
* PHP's DOM classes are recursive but don't provide an implementation of
* RecursiveIterator. This class provides a RecursiveIterator for looping over DOMNodeList
*/
class DOMNodeRecursiveIterator extends ArrayIterator implements RecursiveIterator {
public function __construct (DOMNodeList $node_list) {
$nodes = array();
foreach($node_list as $node) {
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mi>o</mi><mi>d</mi><mi>e</mi><mi>s</mi><mo stretchy="false">[</mo><mo stretchy="false">]</mo><mo>=</mo></mrow><annotation encoding="application/x-tex">nodes[] = </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">n</span><span class="mord mathnormal">o</span><span class="mord mathnormal">d</span><span class="mord mathnormal">es</span><span class="mopen">[</span><span class="mclose">]</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span></span></span></span>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);
}
}
?>
17 years ago
In PHP 5.2.5 (Windows) it is not possible to iterate correctly over the DOMNodeList object returned by DOMNode->childNodes using foreach. Instead I had to use the for loop in conjunction with the item() method of DOMNodeList for iterating over all child nodes correctly.
I don't know whether this is really a bug, but apparently it is.
4 years ago
It's worth to mention that DOMNodeList is not an Array, so you have to convert first to an array before to use for, foreach or array_map, array_filter, array_walk functions.
Use iterator_to_array to make the conversion ( since 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( <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>S</mi><mi>o</mi><mi>m</mi><msub><mi>e</mi><mi>N</mi></msub><mi>o</mi><mi>d</mi><mi>e</mi><mi>L</mi><mi>i</mi><mi>s</mi><mi>t</mi><mo stretchy="false">)</mo><mi>a</mi><mi>s</mi></mrow><annotation encoding="application/x-tex">Some_NodeList ) as </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.05764em;">S</span><span class="mord mathnormal">o</span><span class="mord mathnormal">m</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.10903em;">N</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord mathnormal">o</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord mathnormal">L</span><span class="mord mathnormal">i</span><span class="mord mathnormal">s</span><span class="mord mathnormal">t</span><span class="mclose">)</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span></span></span></span>node )
@var_dump( $node );
</code>
Hope is usefull.
15 years ago
Note that $length is calculated (php5.3.2).
Iterating over a large NodeList may be time expensive.
Prefer : <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mi>b</mi><mo>=</mo></mrow><annotation encoding="application/x-tex">nb = </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">nb</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span></span></span></span>nodelist->length;
for($pos=0; <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mi>o</mi><mi>s</mi><mo><</mo></mrow><annotation encoding="application/x-tex">pos<</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7335em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span><span class="mord mathnormal">os</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel"><</span></span></span></span>nb; $pos++)
Than:
for($pos=0; <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mi>o</mi><mi>s</mi><mo><</mo></mrow><annotation encoding="application/x-tex">pos<</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7335em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span><span class="mord mathnormal">os</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel"><</span></span></span></span>nodelist->length; $pos++)
I had a hard time figuring that out...
17 years ago
You can modify, and even delete, nodes from a DOMNodeList if you iterate backwards:
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi><mi>l</mi><mi>s</mi><mo>=</mo></mrow><annotation encoding="application/x-tex">els = </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">s</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span></span></span></span>document->getElementsByTagName('input');
for ($i = <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi><mi>l</mi><mi>s</mi><mo>−</mo><mo>></mo><mi>l</mi><mi>e</mi><mi>n</mi><mi>g</mi><mi>t</mi><mi>h</mi><mo separator="true">;</mo><mo>−</mo><mo>−</mo></mrow><annotation encoding="application/x-tex">els->length; --</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7778em;vertical-align:-0.0833em;"></span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">s</span><span class="mord">−</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mpunct">;</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">−</span><span class="mord">−</span></span></span></span>i >= 0; ) {
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi><mi>l</mi><mo>=</mo></mrow><annotation encoding="application/x-tex">el = </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span></span></span></span>els->item($i);
switch ($el->getAttribute('name')) {
case 'MAX_FILE_SIZE' :
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi><mi>l</mi><mo>−</mo><mo>></mo><mi>p</mi><mi>a</mi><mi>r</mi><mi>e</mi><mi>n</mi><mi>t</mi><mi>N</mi><mi>o</mi><mi>d</mi><mi>e</mi><mo>−</mo><mo>></mo><mi>r</mi><mi>e</mi><mi>m</mi><mi>o</mi><mi>v</mi><mi>e</mi><mi>C</mi><mi>h</mi><mi>i</mi><mi>l</mi><mi>d</mi><mo stretchy="false">(</mo></mrow><annotation encoding="application/x-tex">el->parentNode->removeChild(</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7778em;vertical-align:-0.0833em;"></span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord">−</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span><span class="mord mathnormal">a</span><span class="mord mathnormal">re</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.10903em;">tN</span><span class="mord mathnormal">o</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord">−</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">re</span><span class="mord mathnormal">m</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.07153em;">C</span><span class="mord mathnormal">hi</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">d</span><span class="mopen">(</span></span></span></span>el);
break;
case 'inputfile' :
$el->setAttribute('type', 'text');
//break;
}
}
17 years ago
I have done some testing and have found 2 results:
(My System: Win XP with PHP 5.2.1)
1) Iteration with foreach does function correctly as "james dot j dot hackett at gmail dot com" writes, _if_ you only do readonly stuff with foreach or minor writings of some attributes.
2) foreach does not function, if you are doing some DOM-Operations while iterating. In my situation it was adding the iterated $node as an child to an new node:
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mi>e</mi><mi>w</mi><mi>N</mi><mi>o</mi><mi>d</mi><mi>e</mi><mo>=</mo></mrow><annotation encoding="application/x-tex">newNode = </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">n</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.10903em;">wN</span><span class="mord mathnormal">o</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span></span></span></span>dom->createElement('newNode') ;
foreach ($nodeList as $node) {
echo $node->nodeValue ;
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mi>e</mi><mi>w</mi><mi>N</mi><mi>o</mi><mi>d</mi><mi>e</mi><mo>−</mo><mo>></mo><mi>a</mi><mi>p</mi><mi>p</mi><mi>e</mi><mi>n</mi><mi>d</mi><mi>C</mi><mi>h</mi><mi>i</mi><mi>l</mi><mi>d</mi><mo stretchy="false">(</mo></mrow><annotation encoding="application/x-tex">newNode->appendChild(</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7778em;vertical-align:-0.0833em;"></span><span class="mord mathnormal">n</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.10903em;">wN</span><span class="mord mathnormal">o</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord">−</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">a</span><span class="mord mathnormal">pp</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">d</span><span class="mord mathnormal" style="margin-right:0.07153em;">C</span><span class="mord mathnormal">hi</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">d</span><span class="mopen">(</span></span></span></span>node) ;
}
This only gives you the first element ...
I'm interpreting it as an confusing but correct behavior because of the changes within the $dom-object while appending the node at an additional place ...
So, if you want to do something like 2) use for, length and item() :)james dot j dot hackett at gmail dot com ¶
17 years ago
In Response to 'kassah at gmail'
You don't need to convert a DOMNodeList to an array in order iterate through it using 'foreach'. You can use foreach directly with the DOMNodeList.
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mi>o</mi><mi>d</mi><mi>e</mi><mi>L</mi><mi>i</mi><mi>s</mi><mi>t</mi><mo>=</mo></mrow><annotation encoding="application/x-tex">nodeList = </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">n</span><span class="mord mathnormal">o</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord mathnormal">L</span><span class="mord mathnormal">i</span><span class="mord mathnormal">s</span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span></span></span></span>someDomDocument->getElementsbytagname('user');
foreach ($nodeList as $node) {
echo $node->nodeValue;
}bobvandell at hotmail dot com ¶
17 years ago
That's actually incorrect. You can use function results as objects. It makes building an API for your database very clean and neat. For example:
Our code:
$articles = Node::screate('tags', 123456)->assets('like:title:test')->articles;
We use the above code to get articles that are linked to assets that are linked to a specific tag in our database.
17 years ago
Addition to my first note:
An traditional for-loop does not allow you to change the DOM-tree while looping - the effects are the nearly the same as with foreach. So you have to collect the nodes in an array and do the tree-altering stuff within a second loop (looping the array this time ...)