XML.com: XML From the Inside Out
oreilly.comSafari Bookshelf.Conferences.

advertisement

Design Patterns in XML Applications
by Fabio Arciniegas A. | Pages: 1, 2, 3, 4, 5, 6

Contents

Design Patterns in XML Applications
Command Pattern
Flyweight Pattern
Wrapper Pattern
Iterator Pattern
Bibliography

Synopsis

Iterator is a behavioral pattern used to access the elements of an aggregate sequentially, without exposing the aggregate's underlying representation. It is particularly useful when you want to encapsulate special logic for the traversal of a structure like a DOM tree.

Iterator Pattern Structure
Figure 8. Iterator Pattern Structure

XML Context

Suppose you are writing a tool that uses the DOM as its internal data representation mechanism. Presumably, there are a lot of actions you want to perform on the members of this collection of elements: search for a particular element, delete all elements with a given name, print elements of certain type, etc.

Since you have read the command pattern section, you decide to implement those actions as Commands, so now you have a nice, extensible way of working with those elements:

        applyToAll(AbstractCommand action) {
     // traverse the whole tree applying action to each
     // node
  }

This is good. However, you start to notice different traversals can work better in some cases, and some actions only need to work on certain kind of objects. So you start wondering about a way to isolate the traversal logic from the rest of the program.

The solution is in the iterator pattern. Using the iterator pattern you can create a parametric method applyAll that expects not only a generic action, but a generic iterator:

        applyToAll(AbstractCommand action, AbstractIterator iterator) {
    for(iterator.reset(); !iterator.atEnd(); iterator.next()) { 
       action.target(iterator.value());
       action.do();
    }
  }

Now you can invent iterators for all kinds of traversals: pre-order, post-order, in-order, pre-order only over text elements, etc., without having to change a single line of your (already compact and elegant!) method.

Example

The iterator presented traverses the collection (the DOM) by levels, printing first all CD elements, then all title, year, artist, and finally all the text elements. Here is the code for such an iterator:

Iterator Sample code

/**
 **************************************************************************
 * Name: LevelIterator
 * Description: This iterator traverses the tree by levels.
 *              Note that it could be replaced in the main program for 
 *              any other iterator conforming with AbstractIteratorIF,  
 *              without changing anything in the main program logic.
 **************************************************************************
 */
import org.w3c.dom.*;
import java.util.Vector;

public class LevelIterator implements AbstractIteratorIF {
    public boolean end() {
 return (aux.size() == 0);
    }
    public void next() {
 if(aux.size() > 0) {
     current = (Node) aux.elementAt(0); //first get the new next element
     aux.removeElementAt(0);
 }
 // now add all of its children to the end... a typical
 // level traversal.
 if (current.hasChildNodes()) {
             NodeList nl = current.getChildNodes();
             int size = nl.getLength();
             for (int i = 0; i < size; i++) {
                 aux.addElement(nl.item(i));
              }
         }
    }
    public Node getValue() {
 return current;
    }
    public LevelIterator(Node c) {
 current = c;
 aux.addElement(current);
    }
    Node current;
    Vector aux = new Vector(); //auxiliar vector for the sublevels 
}

This is the output of the IteratorDemo program that uses the previous iterator to walk the music.xml example from the Flyweight section.

Iterator Sample Output

--
Node Name: collection 
NodeValue: null
--
Node Name: #text 
NodeValue: 
--
Node Name: cd 
NodeValue: null
--
Node Name: cd 
NodeValue: null
--

...

--
Node Name: #text 
NodeValue: Eno, Brian
--
Node Name: #text 
NodeValue: The Drop
--
Node Name: #text 
NodeValue: 1999

Please refer to iterator.zip for the complete code.

Summary of Common XML Uses

The iterator pattern is useful in XML applications when:

  • You need to encapsulate the way you walk a given collection. Most of the time in XML applications, this collection will be a DOM tree.

Iterator concludes this overview of the use of design patterns in XML applications. A forthcoming article will present an introduction to some patterns with particular applications to XML.

Design patterns are a powerful way to improve the quality and comprehensibility of your XML applications. Make sure to review the bibliography. You will certainly find more ways to boost your XML development.

If you have comments or questions, the author may be contacted at fabio@viaduct.com

Pages: 1, 2, 3, 4, 5, 6

Next Pagearrow