The NodeList interface

DOM stores the lists of children of each node in NodeList objects. This is a very basic indexed list shown in Example 9.13. Indexes start from 0 and continue to one less than length of the list, just like Java arrays.

Example 9.13. The NodeList interface

package org.w3c.dom;

public interface NodeList {
  
  public Node item(int index);
  public int  getLength();

}

Instances of this interface are returned by the getChildNodes() method in the Node interface, as well by various methods in its sub-interfaces we’ll encounter in the next chapter.

The actual data structure that backs this interface can be a linked list, an array, or something else. Details vary from implementation to implementation. Whatever the concrete data structure is, you can use node lists to simplify operations that iterate over children. For example, the processNode() method in Example 9.11 could be rewritten using NodeList instead of getNextSibling() like this:

  public void followNode(Node node) throws IOException {
    
    printer.writeNode(node);

    // Process the children
    NodeList children = node.getChildNodes();
    for (int i = 0; i < children.getLength(); i++) {
      Node child = children.item(i);
      followNode(child); // recursion
    }    
    
  }

This still walks the tree like several of the earlier programs. However, the algorithm is somewhat more obvious because it uses more list iteration and less recursion. (Recursion is still necessary to descend the tree but not to move from one sibling to the next.)

Whether or not this variant is more efficient than the original version that only uses the Node interface depends on the concrete implementation. It may indeed be faster if the implementation classes store children in arrays. It may not be if the implementation classes use linked lists. Either way the difference is not likely to be significant. Which approach feels more natural to you is a lot more important than the marginal speed you might gain by picking one over the other.

Node lists are live. That is, if you add or delete a node from the list the change is reflected in the document and vice versa. This can make it a little tricky to keep track of where you are in the list since the length can keep changing, and nodes can move from one place in the list to another.

Node lists (and pretty much everything else in DOM) are not thread safe. If one thread is writing to or modifying a NodeList, while another thread is reading from it, data corruption is almost guaranteed. Because node lists are live, code can be unsafe even when no other thread has a reference to that particular node list, as long as some other thread has a reference to the Document from which the NodeList was built.


Copyright 2001, 2002 Elliotte Rusty Haroldelharo@metalab.unc.eduLast Modified May 26, 2002
Up To Cafe con Leche