next:
Motivation Intent

Apply one tree structure to another. Both trees must support visitors.

next: Applicability Motivation

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.

Picture of XmlObject Hierarchy

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.

Picture of XmlVisitor Hierarchy

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:

  1. Build trees for the XML document and the DTD document.
  2. Construct both visitor objects.
  3. Invoke the register method on the XmlDtdVisitor object passing it the XmlDocVisitor object. As you can see from the picture, this method invokes the XmlDocVisitor.register method passing itself (XmlDtdVisitor) as a parameter. The XmlDocVisitor.register method saves a pointer to XmlDtdVisitor in the xdv variable.
  4. Invoke the visitXml method on XmlDtdVisitor passing it the Document object of the XmlObject hierarchy representing the DTD document. This causes the XmlDtdVisitor methods to be invoked as the DTD tree is traversed. The XmlDtdVisitor methods build some kind of "rules" structure(s) for various kinds of XML objects. The details of this structure are beyond the scope of this document.
  5. Invoke the visitXml method on XmlDocVisitor passing it the Document object of the XmlObject hierarchy representing the XML document. This causes the XmlDocVisitor methods to be invoked as the XML tree is traversed. The XmlDocVisitor methods invoke the corresponding "apply" methods in XmlDtdVisitor. As an example, the XmlDocVisitor.visitEntity method invokes the XmlDtdVisitor.applyEntity method. In general, the XmlDocVisitor.visitXxx method invokes the XmlDtdVisitor.applyXxx method, where Xxx is Document, Entity, Attribute, ProcessInstruction, etc.
  6. The "apply" methods of XmlDtdVisitor apply the appropriate part(s) of the "rules" structure, built in the XmlDtdVisitor.visitXxx methods, to the objects passed to them. It is these methods which will validate the XML document.
  • next:
StructureApplicability

    Use the DoubleVisitor pattern when

    next:
Participants Structure

    next: Collaborations Participants

    next: Consequences Collaborations

    next: Implementation Consequences

    Some of the benefits and liabilities of the DoubleVisitor pattern are as follows:

    next:
Known Uses Sample Code

    next: Related Patterns Known Uses

    next:
navigation Related Patterns

    :