OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.


Help: OASIS Mailing Lists Help | MarkMail Help



   RE: SAX and stuff ...

[ Lists Home | Date Index | Thread Index ]
  • From: Michael Brennan <Michael_Brennan@Allegis.com>
  • To: "'Xml-Dev (E-mail)'" <xml-dev@lists.xml.org>
  • Date: Tue, 25 Jul 2000 12:35:42 -0700

I've used essentially the same approach, and it has worked well. However,
more recently I switched to a different approach. I felt that this approach
somewhat constrains extensibility. Each node that accepts children must be
responsible for creating every possible type of child.

My more recent approach is to have an "addChild" method on what you are
calling the ParserListener (which I called "ElementHandler" in my
implementation). Then, I use a simple Hashtable (loaded from a Java
Properties file) to map element names to a class that is loaded via
reflection (just as Stefan Haustein noted in another post). The BaseHandler
that is maintaining the stack of current ElementHandlers invokes "addChild"
on the parent ElementHandler after instantiating a new ElementHandler.

This child, of course, needs to derive from a type that the parent knows how
to deal with, but at least it can exploit polymorphism, here, and the parent
need not be responsible for knowing every possible specialization that can
be instantiated.

> From: jar@miami.integratus.com [mailto:jar@miami.integratus.com]On
> [...]
>   I use DTDs; I think you should, too.  But, with that in
> mind, here is
> how I do it (all examples in C++):
>   o Create an ObjectFactory (in the GoF object sense) that can make
> objects based on string names.
>   o Make a ParserListener interface that has stuff like this in it:
> <interface>
> public:
>     // start creating a child object.
>   virtual ParserListener* createChildObject( const string
> object ) = 0;
>   // complete a child object.
>   virtual ParserListener* completeChildObject( const string object ) =
> 0;
>   // get the value of an object attribute.
>   virtual const string getAttribute( const string newKey ) = 0;
>   // set attribute "key" to value "value" for this node.
>   virtual void setAttribute( const string key, const string
> value ) = 0;
> protected:
>   // clean up my children after parsetime.
>   virtual void arrangeChildren() = 0;
> </interface>
>   o Extend the BaseHandler into a class that has a private member that
> is a ParserListener, and implement a stack of previous ParserListener
> objects.
>   o StartElement() pushes the current ParserListener onto the
> stack and
> sets it to the return of a call to the current ParserListener's
> createChildObject() method.  The createChildObject() method
> makes a call
> to the aforementioned ObjectFactory and returns the new object (which,
> itself, is also a ParserListener).
>   o EndElement() calls the ParserListener's
> completeChildObject() method
> and pops the old ParserListener off of the stack (reassigning the
> current ParserListener to it).  The completeChildObject() calls calls
> the object's arrangeChildren() method to do any final cleanup and
> reorganization of the tree that was built from the parse.
> [...]


News | XML in Industry | Calendar | XML Registry
Marketplace | Resources | MyXML.org | Sponsors | Privacy Statement

Copyright 2001 XML.org. This site is hosted by OASIS