[XML-SIG] Re: XML-SIG digest, Vol 1 #156 - 1 msg

Henk Jansen H.Jansen@math.tudelft.nl
Mon, 30 Nov 1998 10:49:24 +0100 (MET)


> A.M. Kuchling wrote:
> 
> > However, this change really makes the distinction between walk() and
> > walk1() unnecessary.  walk() is basically there as a wrapper for
> > walk1(), to get the root element if it's a Document node; if we just
> > traverse all the children, this is consistent for any node type so
> > walk() and walk1() could be collapsed into one function.  This will
> > break code that subclasses Walker and overrides walk() or walk1() with
> > something customized.
> >
> > What do people think should be done?  Just fix walk(), or merge walk()
> > and walk1()?
> >
> 
> I think they should be merged.  The current solution also does not allow you to
> print comments, doc types, or anything else outside of the root element....
> 
> If you are worried about breaking customizations on this interface, you could
> define walk1 and just have it call walk until everyone gets thier code
> modified....

Since the DOM hierarchy resembles much of a general tree type, I wonder if the following walk method, which is quite general, could serve as a DOM tree walker interface (Note: I haven't checked the DOM code so I don't know how general it is already. I'm also not sure if it will break code or not.):

def walk (_, co):
    """
    Walk the tree with co a callable object having:
	 .atleaf()
	 .preorder()
	 .postorder()
    methods.
    """
    assert ... _co_has_these_methods_ ...
    _._walk (co)

def _walk (_, co, depth=1):
    __doc__ = Node.walk.__doc__
    for child in _.leaves:
	co.atleaf (child, depth)
    for child in _.branches:
        co.preorder (child, depth):
	child._walk (co, depth=depth+1)
	co.postorder (child, depth):
    return co


For instance, printing the tree goes as follows:


import StringIO

class TreeRepr:

    def __init__ (_):
	_.t = StringIO.StringIO ()

    def atleaf (_, child, depth):
         _.t.write ("--"*depth+`child`+'\n')

    def preorder (_, child, depth):
         _.t.write ("--"*depth+`child`+'\n')

    def postorder (_, child, depth):
        pass 


class Node:

    ... general tree node methods.

    def __repr__ (_)
        repr = TreeRepr()
        repr = _walk (repr)
        return repr._t.getvalue()


Dependig on the callable object, all sorts of functionality can be exploited when walking the tree: translation, checking, finding, etc.

The _walk procedure could be exteded with a "break condition":

def _walk (_, co, depth=1):
    __doc__ = Node.walk.__doc__
    for child in _.leaves:
	if co.atleaf (child, depth):
	    # stop walking the current list of leaves
	   break
    for child in _.branches:
        if co.preorder (child, depth):
	    # stop walking the current branch
	    break
	child._walk (co, depth=depth+1)
	if co.postorder (child, depth):
	    # stop walking the current branch
	    break
    return co

This means that walking the tree can be aborted when one of the co.<methods>
returns a true value.

Henk.

-- 
  -----------------------------------------------------------------------
 | Henk Jansen   http://dutita0.twi.tudelft.nl/WAGM/people/H.Jansen.html |
 | Delft University of Technology             |  hjansen@math.tudelft.nl |
 | > Information Technoloy and Systems (ITS)  |      Mekelweg 4, 2628 CD |
 | >> Mathematics (TWI)                       |   Delft, The Netherlands |
 | >>> Applied Analysis (TA)                  | phone: +31(0)15-278-7295 |
 | >>>> Analysis of Large Scale Models (WAGM) | fax:   +31(0)15-278-7209 |
  -----------------------------------------------------------------------