@@ -28,23 +28,22 @@ class TreeWalker(_base.NonRecursiveTreeWalker):
2828 to avoid using recursion, returns "nodes" as tuples with the following
2929 content:
3030
31- 1.An Element node serving as *context* (it cannot be called the parent
32- node due to the particular ``tail`` text nodes.
33-
34- 2. Either the string literals ``"text"`` or ``"tail"`` or a child index
35-
36- 3. A list used as a stack of all ancestor *context nodes*. It is a
37- pair tuple whose first item is an Element and second item is a child
38- index.
31+ 1.The current element
32+
33+ 2. The index of the element relative to its parent
34+
35+ 3. A stack of ancestor elements
36+
37+ 4. A flag "text", "tail" or None to indicate if the current node is a
38+ text node; either the text or tail of the current element (1)
3939 """
40-
41- def getNodeDetails (self ,node ):
40+ def getNodeDetails (self ,node ):
4241if isinstance (node ,tuple ):# It might be the root Element
43- elt ,key ,parents = node
44- if key in ("text" ,"tail" ):
45- return _base .TEXT ,getattr (elt ,key )
42+ elt ,key ,parents , flag = node
43+ if flag in ("text" ,"tail" ):
44+ return _base .TEXT ,getattr (elt ,flag )
4645else :
47- node = elt [ int ( key )]
46+ node = elt
4847
4948if not (hasattr (node ,"tag" )):
5049node = node .getroot ()
@@ -61,54 +60,60 @@ def getNodeDetails(self, node):
6160else :
6261#This is assumed to be an ordinary element
6362return _base .ELEMENT ,node .tag ,node .attrib .items (),len (node )or node .text
64-
63+
6564def getFirstChild (self ,node ):
66- if isinstance (node ,tuple ):# It might be the root Element
67- elt ,key ,parents = node
68- assert key not in ("text" ,"tail" ),"Text nodes have no children"
69- parents .append ((elt ,int (key )))
70- node = elt [int (key )]
65+ if isinstance (node ,tuple ):
66+ element ,key ,parents ,flag = node
7167else :
72- parents = []
73-
74- assert len (node )or node .text ,"Node has no children"
75- if node .text :
76- return (node ,"text" ,parents )
68+ element ,key ,parents ,flag = node ,None , [],None
69+
70+ if flag in ("text" ,"tail" ):
71+ return None
7772else :
78- return (node ,0 ,parents )
79-
73+ if element .text :
74+ return element ,key ,parents ,"text"
75+ elif len (element ):
76+ parents .append (element )
77+ return element [0 ],0 ,parents ,None
78+ else :
79+ return None
80+
8081def getNextSibling (self ,node ):
8182if isinstance (node ,tuple ):
82- elt ,key ,parents = node
83- if key == "text" :
84- key = - 1
85- elif key == "tail" :
86- elt ,key = parents .pop ()
87- else :
88- # Look for "tail" of the "revisited" node
89- child = elt [key ]
90- if child .tail :
91- parents .append ((elt ,key ))
92- return (child ,"tail" ,parents )
83+ element ,key ,parents ,flag = node
9384else :
9485return None
95-
96- # case where key were "text" or "tail" or elt[key] had a tail
97- key += 1
98- if len (elt )> key :
99- return (elt ,key ,parents )
86+
87+ if flag == "text" :
88+ if len (element ):
89+ parents .append (element )
90+ return element [0 ],0 ,parents ,None
91+ else :
92+ return None
10093else :
101- return None
102-
94+ if element .tail and flag != "tail" :
95+ return element ,key ,parents ,"tail"
96+ elif key < len (parents [- 1 ])- 1 :
97+ return parents [- 1 ][key + 1 ],key + 1 ,parents ,None
98+ else :
99+ return None
100+
103101def getParentNode (self ,node ):
104102if isinstance (node ,tuple ):
105- elt ,key ,parents = node
106- if parents :
107- elt ,key = parents .pop ()
108- return elt ,key ,parents
109- else :
110- return elt
103+ element ,key ,parents ,flag = node
111104else :
112105return None
106+
107+ if flag == "text" :
108+ if not parents :
109+ return element
110+ else :
111+ return element ,key ,parents ,None
112+ else :
113+ parent = parents .pop ()
114+ if not parents :
115+ return parent
116+ else :
117+ return parent ,list (parents [- 1 ]).index (parent ),parents ,None
113118
114119return locals ()