[jdom-interest] new to jdom .. and many questions

Dennis Sosnoski dms at sosnoski.com
Tue Aug 27 21:24:03 PDT 2002


If you truly want to navigate the tree in a breath-first manner it's 
going to be messy. Probably the easiest way of doing this is to have a 
recursive walker that you pass a depth parameter to. This would look 
something like this:

Element nextAtDepth(Element from, int depth) {
  // depth must always be <= 0
  if (depth > 0) {  // meaning we need to go deeper in the tree
    if (from.hasChildren()) {
      Iterator iter = from.getChildren().iterator();  // check all 
children to find descendant at depth
      while (iter.hasNext()) {
        Element found = nextAtDepth((Element)iter.next(), depth-1);
        if (found != null) {
          return found;
        }
      }
    }
    // no descendants at depth we want
    return null;
  } else {
    // next at same level as this element, loop to move up tree until 
sibling found
    Element parent;
    Element match = from;
    while ((parent = match.getParent()) != null) {
      // see if there's a sibling following our current element
      List children = parent.getChildren();
      int index = children.indexOf(from);
      if (index >= 0)
        while ((index+1) < children.size()) {
          // if this is our first time through this loop we've found the 
next one; otherwise we need to descend
          Element sibling = (Element)children.get(index+1);
          if (depth == 0) {
            return sibling;
          } else {
            Element found = nextAtDepth(sibling, depth);
            if (found != null) {
              return found;
            }
          }
          // try next sibling for descendants at target depth
          index++;
        }
      }
      // move up the tree for next pass through this loop
      depth++;
      match = parent;
    }
  }
}

There might be a cleaner way of structuring this, but I'm not going to 
worry about it. The basic idea is that you mix two techniques; one finds 
the first descendant at a specified depth from the supplied element, the 
other finds the next sibling of the supplied element (or if there is 
none, the first child element of the next sibling of the parent of the 
supplied element, or the first grandchild of the next sibling of the 
grandparent, etc.).

The first element in a breath-first walk is always the root element. The 
next one is returned by this method when you call it with (root, 1). You 
can then call it with (current, 0) until it returns null, at which point 
you call it with (root, 2) to find the first element at the next level. 
Keep repeating until you reach some depth n where (root, n) returns 
null, at which point you're done.

Hope that helps.

  - Dennis

Azrael wrote:

> Of course, you're very much correct regarding my first question.. it's
> late and I wasn't thinking straight :)
> I badly explained with extra detail what would have been simpler with a
> shorter question.. of how to find if it was the very last element or not.
> I don't really want to be learning to use XPATH in java right now.. 
> and so will go for the iterating method you suggest..
> finding next sibling as you say is easy enough.. but I am a little 
> unsure about how to navigate the jdom tree breadth first using the 
> Lists.. does anyone have example code that I could use as a guide?
>





More information about the jdom-interest mailing list