Using PHP array functions on a DOMDocument NodeList

The PHP DOMDocument class implements the W3C DOM. However, PHP implementation is quite different from its JavaScript counterpart, so it's not so easy to make something like this:

$dom = new DOMDocument();
$dom->load('test.xml');

$items = $dom->getElementsByTagName('item');
$items = array_slice($items, 0, 3); // returns an error

The fact is that we're actually dealing with a NodeList collection of DOM element objects, so it's not possible to use array functions on them (with JavaScript there are a couple of tricks to perform this operation, though). I have to test more extensively this feature to solve this problem. So far I've played a little bit with PHP iterators, but I wasn't lucky, perhaps because I'm using a wrong approach. I'll let you know, so stay tuned.

4 thoughts on “Using PHP array functions on a DOMDocument NodeList”

  1. I would love to find out what kind of code you're using? I've been attempting similar ...

    $arrNodes = self::iterate_nodes($nodelist);
    echo 'pre'; var_dump($config); echo '/pre';

    public static function iterate_nodes(DOMNodeList $nodelist) {
    $arr = array();
    for($i = 0; $i < $nodelist->length; ++$i) {
    $element = $nodelist->item($i);
    if(
    $element instanceof DOMElement &&
    $element->nodeName != '#text'
    ) {
    $arr[$i] = array_merge(
    self::iterate_nodes($element->childNodes),
    array($element->nodeName=>null)
    );
    }
    elseif(
    $element instanceof DOMElement &&
    $element->nodeName == '#text'
    ) {
    $arr[$i][$element->nodeName] = $element->nodeValue;
    }
    } // end for($i ...
    return $arr;
    } // end def

    i've tried using combo's of $element->nodeType and php DOM constants for branching and 'while', 'foreach', and 'for' loops with little success. It seems almost impossible to step thru the object keys! On top of which fetching attributes is another issue ... the function DOMElement::attributes does not work with my current version of php(5.1.6x64) so fetching attribute data is anything but dynamic.

    please do tell your side of the story

  2. Thanks for the comment. Basically, DOM nodes are objects that inherit directly from the DOMNode interface (in HTML, there's an HTMLElement interface). The problem is that array methods don't work on objects. I've also tried to use PHP iterators on the NodeList but probably I got it wrong so it didn't work. I think that iterators would probably be a feasible solution, but at the moment I'm really busy and I do not have the time to run some tests. However, if you need help, send me an email on Saturdays or Sundays and I'll try to help you. Bye :-)

  3. after googling around managed to put this together :) ... works for me ... maybe it'll help you too.

    public static function iterate_nodes(DOMNodeList $nodelist) {
    $arr = array();
    for($i = 0; $i < $nodelist->length; ++$i) {
    $element = $nodelist->item($i);
    switch($element->nodeType) {
    case(XML_TEXT_NODE):
    $arr = $element->data;
    break;
    case(XML_CDATA_SECTION_NODE):
    $arr = $element->data;
    break;
    case(XML_ELEMENT_NODE):
    $arr[$i][$element->nodeName] =
    self::iterate_nodes($element->childNodes);
    if($element->attributes) {
    for(
    $j = 0;
    $element->attributes->item($j);
    $j++
    ) {
    $attribute =
    $element->attributes->item($j);
    $arr[$i][$element->nodeName][$attribute->nodeName] =
    $attribute->nodeValue;
    }
    }
    break;
    }
    } // end for($i ...

    return $arr;
    }

Leave a Reply

Note: Only a member of this blog may post a comment.