[XML-SIG] Functional interface to XML?

Paul Prescod paul@prescod.net
Tue, 16 Feb 1999 11:35:15 -0600


uche.ogbuji@fourthought.com wrote:
> 
> I don't think we've thought of this, and it's actually a good idea.  


I'd better go patent it!

> We
> primarily use it to emit HTML or transformed (non-FO) XML for now, but we
> could provide a SAX interface to make it more useful.

If you are just emitting HTML wouldn't it be easier and more efficient to
use a "reverse SAX" output engine instead of building and walking a DOM. I
believe XSL is designed so that you can output everything as you generate
it.

> Well, I'm still not sure I get your meaning, but the pattern-matching code is
> pretty well de-coupled from the tree-visiting portion.  This is to allow
> easier updates as the XSL WG modifies their spec.  I'm not sure how usable the
> API would be when exposed outside 4XSL, but we can certainly keep such
> potential use in mind.
> 
> Are you thinking of maybe extending the transformation facilities of a
> style-sheet using Python, rather than the erstwhile ECMAScript?

Well that goes without saying. :)

What I am *really* interested in is answer Cee's de Groot's question
(which is also mine) of an API that *Python programmers* can use that acts
like XSL or DSSSL but uses Python syntax. Think of it this way: if XSL
does 90% of what you want then you want to just extend it with Python. If
XSL only does 20% of what you want then you want those XSL features in
Python without the XSL stylesheet syntax.

Imagine something like this:

"""
Warnings:

Of course you should use your own descretion in deciding whether
implementing this idea makes sense, especially since you've already done
so much work.

I move between the DOM, the grove and a few other APIs so I can never keep
them straight in my head. So the method calls and class names below are
mostly fanciful.

Also, I've left out the required __init__ methods to set up object data.
"""
visitor = xsllib.XSLPatternVisitor()

def DoSomethingWithDocTitles( node, engine ):
    blah
    engine.ApplyTemplates( node, "TITLE" )
    blah
    engine.ApplyTemplates( node, ".//FN" )

visitor.register( DoSomethingWithTitles, "DOC/TITLE")

def DoSomethingWithChapterTitles( node, engine ):
    blah
    engine.ValueOf( node )
    blah

visitor.register( DoSomethingWithTitles, "CHAPTER/TITLE")

def DoSomethingWithFootnotesInChapters( node, engine ):
    blah
    for i in node.Children: # or is "Content" in DOM
       blah
    blah

visitor.register( DoSomethingWithFootnotesInChapters, "CHAPTER//FN" )

"""
Do you see what I'm getting at? 

Now you could imlement "real" XSL in terms of these primitives.
"""

class ApplyTemplatesNode( ElementNode ):
    def invoke( self ):
        self.engine.ApplyTemplates( self )

class LiteralResultNode( ElementNode ):
    def invoke( self ):
        self.result.ElementEvent( self.TagName )

class LiteralResultTextNode( TextNode ):
    def invoke( self ):
        self.result.TextEvent( self.TextValue )

... 

(somewhere else)

class xsl_templateRuleNode( ElementNode ):
    def __init__( self, visitor, tagName, template, attrs... ):
        self.visitor.register( self.template.invoke, attrs["PATTERN"] )

Hope that helps!

-- 
 Paul Prescod  - ISOGEN Consulting Engineer speaking for only himself
 http://itrc.uwaterloo.ca/~papresco

If you spend any time administering Windows NT, you're far too familiar 
with the Blue Screen of Death (BSOD) which displays the cause of the 
crash and gives some information about the state of the system when 
it crashed.  -- "Microsoft Developer Network Magazine"