спасибо ... пока я ждал, я пытался решить это сам ...
отказ от ответственности: я написал это до того, как Фердинанд придумал окончательную версию своего превосходного ответа
на самом деле ваше решение, по-видимому, отлично работает для дерева, состоящего из обычных списков Python ... к сожалению, org.w3c.dom.Node особенно "тупой" ... getChildNodes () фактически создает объект с именем NodeList, который, очевидно, является списком (Java Array) какого-то рода, остается герметически закрытым от самоанализа ... в частности, dir () скажет вам, что класс его поля "childNodes" - это org.apache.xerces.dom.DeferredElementImpl "... и мой опыт показывает, что с чем-то, заканчивающимся на" Impl ", играть будет не очень весело ...
Поэтому я, очевидно, не нашел способа передать метод в качестве параметра и вызвать его ... даже с более податливым Python-подобным классом. В настоящее время мне не ясно, как вы вызываете метод, который вы передаете в качестве параметра ... в любом случае ...
Итак, ниже представлены мои 3 предложения, довольно очевидные: 1) глубина вначале 2) выбор глубины или ширины вначале 3) то же самое, но с доставкой чего-либо с указанием глубины (так что вы можете форматировать распечатки) например).
С решением № 3 я был вынужден создать новый класс, к сожалению, потому что я обнаружил, что было невозможно, например, добавить атрибут к объекту Node ... очевидно, у Jython есть ограничения и "примеси" по сравнению с Python. Я знаю, что есть модули Python для работы с XML и т. Д. ... мы рассмотрим это в свое время.
(NB, конечно, один из замечательных аспектов Jython заключается в том, что вы можете постепенно переходить с Java на Python).
Было бы интересно, если кто-нибудь из опытных людей Python / Jython имеет какие-либо комментарии ...
только для глубины:
def depthFirstTreeEnumeration( node ):
nodeList = node.getChildNodes()
for i in range( nodeList.getLength()):
childNode = nodeList.item( i )
yield childNode
for item in depthFirstTreeEnumeration( childNode ):
yield item
выбор глубины или ширины
def treeEnumeration( node, depthFirst = True ):
nodeList = node.getChildNodes()
for i in range( nodeList.getLength()):
childNode = nodeList.item( i )
yield childNode
if depthFirst:
for item in treeEnumeration( childNode ):
yield item
if not depthFirst:
for i in range( nodeList.getLength()):
childNode = nodeList.item( i )
for item in treeEnumeration( childNode, False ):
yield item
выбор глубины или ширины, с указанием глубины данного узла
class NodeWrapper():
def __init__(self, node, depth ):
self.node = node
self.depth = depth
def __repr__( self ):
return "node %s, depth %d" % (self.node, self.depth)
def treeEnumerationShowDepth( node, depth = 0, depthFirst = True ):
nodeList = node.getChildNodes()
for i in range( nodeList.getLength()):
wrapper = NodeWrapper( nodeList.item( i ), depth )
yield wrapper
if depthFirst:
for item in treeEnumerationShowDepth( wrapper.node, depth + 1 ):
yield item
if not depthFirst:
for i in range( nodeList.getLength()):
childNode = nodeList.item( i )
for item in treeEnumerationShowDepth( childNode, depth + 1, False ):
yield item
from org.w3c.dom import Node
for wrapper in treeEnumerationShowDepth( dom.getDocumentElement(), 0, False ):
print "%snode: %s" % ( wrapper.depth * " ", wrapper.node )