MyArch.com

Java Frameworks

API   Contents

Dynamic adjustment of traversal depth

The task of selective traversal can be accomplished by dynamically changing the depth of traversal for different nodes (branches). If we need to process only the branch with ID="K.TAMURA", the initial maximum depth should be set to 2 (depth of ID level). For the required selected ID node, depth should be adjusted to "unlimited ", so the tree iterator can process children of the node. With this approach, maximum depth can't remain just a static parameter applied to the entire tree. Instead, the original depth should be restored when iterator returns to the level of parent node. In other words, depth becomes an attribute of a level and should be kept in the stack along with other level information (such as current node).

Calling program calls setLevelDepth() method of the iterator to change the maximum depth value for the current node (control node). When all children of the control node are processed and iterator returns to the control node level, the corresponding maximum depth is restored.



import com.myarch.treeiterator.TreeIterator;
import com.myarch.treeiterator.DOMAdapter;

import org.w3c.dom.Node;
import org.w3c.dom.Element;

/**
 * Demonstrates the selecive traversal using setLevelDepth method of
 * the TreeIterator.
 *
 */
public class SelectiveSetDepthTraversal {

  /**
   * Selectively traverses the tree using setLevelDepth.
   * Traverses only the branch of "K.Tamura" and ignores other branches.
   *
   * @param rootNode root of the DOM tree.
   */
  public void traverse ( Node rootNode ) {

    // create iterator, initially it is limited to the ID level
    int idLevel =2;
    TreeIterator tIterator = new TreeIterator ( rootNode, new DOMAdapter(), idLevel);
    Node node = null;
    while( ( node=(Node)tIterator.next() )!=null ){
      // print node information
      System.out.println( node.getNodeName()+"="+node.getNodeValue());

      if  ( tIterator.getDepth() == idLevel && (node instanceof Element &&
        ((Element)node).getAttribute( "id").equalsIgnoreCase("K.TAMURA" ))) {

        // this allows iterator to traverse children of the current  node
        tIterator.setLevelDepth( TreeIterator.DEPTH_UNLIMITED);
      }
    }
  }

In simple cases using skipChildren() method yields the same result. setLevelDepth(), however, provides much greater flexibility when it comes to more complex selective processing. It allows for applying different maximum depth to different branches of a tree. Some branches can be processed fully and some partially, up to the required depth. For example, we might need to process all levels for managers and only some levels for other entries in the personnel file.

This approach also allows for depth nesting. setLevelDepth() can be called multiple times, first for the topmost control node, then for the node within the same branch that meets some additional criteria and so on. In other words, coverage of the tree during traversal is defined by the combination of depths specified for the given set of criteria. Every criterion in the set can impose its own depth limitation on the tree. And no matter how complex these criteria are, the traversal is still performed within one loop.

API   Contents