Apply one tree structure to another. Both trees must support visitors.
An XML document can have various kinds of other XML documents applied to it. Two obvious examples are DTD and XLST. I will use the DTD example. This example is made much easier by the fact that a DTD document is an XML document.
An XML document can be represented by a tree of objects which are all inherited from the class XmlObject.
Much is left out here. What is important is that these classes support the visitor pattern. In order to fully implement the visitor pattern, another group of classes is needed. Once again, the classes come from the visitor pattern, but from the "other side" of that pattern, the visitor side.
Here, we see the XmlVisitor class, which is the base class and some visitor classes which inherit from the base class. The first, XmlPrintVisitor, is pretty straight forward. For each object in the XmlObject hierarchy, it simply prints some kind of representation of that object.
One thing is a bit of a variation on the original visitor pattern. As not noted above, the Document class is the public class of the XmlObject hierarchy. The visitXml method of the XmlVisitor class is passed a Document object. It is this method (visitXml) which actually initiates the "visits". Since it is fully implemented in the base class, it probably should not be overridden.
The other two visitor classes are a bit different. In fact, they are the point of this whole pattern.
The first is the XmlDtdVisitor. It will be used to traverse the DTD document. The second is the XmlDocVisitor. It will traverse the XML document. What is missing in this picture is the order in which the client must invoke things:
Use the DoubleVisitor pattern when
Some of the benefits and liabilities of the DoubleVisitor pattern are as follows: