PHP 5.6.38 Released

The DOMNodeList class

(PHP 5, PHP 7)

Class synopsis

DOMNodeList implements Traversable , Countable {
/* Properties */
readonly public int $length ;
/* Methods */
public int count ( void )
DOMNode item ( int $index )
}

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
7.2.0 The Countable interface is implemented and returns the value of the length property.

Table of Contents

add a note add a note

User Contributed Notes 10 notes

up
12
c dot 1 at smithies dot org
10 years ago
You can modify, and even delete, nodes from a DOMNodeList if you iterate backwards:

$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;
  }
}
up
15
ignitedfirestarter at gmail dot com
6 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) {
     
$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);
  }
 
}
?>
up
9
geompse at gmail dot com
8 years ago
Note that $length is calculated (php5.3.2).
Iterating over a large NodeList may be time expensive.

Prefer :
$nb = $nodelist->length;
for($pos=0; $pos<$nb; $pos++)

Than:
for($pos=0; $pos<$nodelist->length; $pos++)

I had a hard time figuring that out...
up
7
brack at wjp dot de
10 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.
up
7
drichter at muvicom dot de
10 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:

$newNode = $dom->createElement('newNode') ;
foreach ($nodeList as $node) {
  echo $node->nodeValue ;
  $newNode->appendChild($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() :)
up
3
james dot j dot hackett at gmail dot com
10 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.

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

foreach ($nodeList as $node) {
    echo $node->nodeValue;
}
up
0
c dot 1 at smithies dot org
10 years ago
I doubt the accuracy of what saad105050 wrote below. In particular, in his example, he seems to assume that $element->getElementsByTagName() will return NULL if there are no matching nodes. This is not what happens; as per the documentation, a DOMNodeList is returned with the length property zero.
up
0
bobvandell at hotmail dot com
10 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.
up
-5
drichter at muvicom dot de
10 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 ...)
up
-11
kassah at gmail dot com
10 years ago
// Converts a DOMNodeList to an Array that can be easily foreached
function dnl2array($domnodelist) {
    $return = array();
    for ($i = 0; $i < $domnodelist->length; ++$i) {
        $return[] = $domnodelist->item($i);
    }
    return $return;
}
To Top