SAX XPath callbacks (was Re: [XML-SIG] Proposal: Marrying SAX2 and DOM)

Paul Prescod paul@prescod.net
Tue, 14 Mar 2000 11:00:35 -0800


Ken MacLeod wrote:
> 
> Does this need to be in the stream head (parser or generator) and be
> part of the SAX binding or is it better implemented as a base class
> for handlers and filters?  I would think the latter.

It was slightly easier to implement it as a filter than as a base class
for the first cut but I will probably try to make it a base class
eventually.

> P.S. Probably too much detail for one message, but it might also be
> beneficial to seperate XPath callbacks and partial-DOM tree support
> into seperate base classes as well.

Here are the current classes:


DOM but not XPath aware:
========================
DOMHandlerBase 
-- a base class for event handlers that expect DOM nodes instead of SAX
events

DOMHandlerAdapter
-- a filter that converts SAX events to DOM events for the
DOMHandlerBase

(various Minidom classes)
-- a small Miniature DOM implementation


Depend on XPath:
================
XPathDispatcher extends DOMHandlerBase
-- implements XPath dispatching. Works as a filter today -- perhaps
could be a base class instead.

DOMBuilder
-- a trivial application of the above that generates a whole DOM and
returns it

MiniDOMFactory
-- an adapter that makes minidom compatible with the PyXPath package.

Initialization
==============

Admittedly, calling it is right now a little ugly because of the layers
of factories:

myhandler = MyXpathHandler()
xpathdispatcher = XPathDispatcher( myhandler )
sax2domhandler = minidom.DOMHandlerAdapter( xpathdispatcher )
p.setDocumentHandler( sax2domhandler )

As long as no method names conflict, we could probably do this all
through inheritance instead of filters. The SAX2DOM base class would
intercept SAX calls and dispatch them to itself as DOM events. A DOM 2
XPath layer would interpret the DOM nodes and dispatch them on itself.

In fact, I think that only a few lines of code need to change. Where I
dispatch to "self.handler" I would just dispatch to "self".

The only uncomfortable part is that subclasses must be very careful to
not mess up the base class' initialization because otherwise it won't
have a chance to collect the list of handlers. There are three ways
around this:

 * have each handler check that the class is properly initialized (ugly)
 * use metaclasses and hope that they don't go away in a future Python
(unsafe)
 * trust the programmer and answer questions on xml-sig

This would be by no means the only inheritable class that really depends
upon proper base class initialization so I guess I should just stop
worrying and learn to trust the programmer. 

-- 
 Paul Prescod  - ISOGEN Consulting Engineer speaking for himself
If all you want is sleep, go to bed.
But if you want to dream, go to Barbados.
    - Timothy Findley, "Barbados: The Very Pineapple of Perfection"