[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 |
-----------------------------------------------------------------------