@@ -28,23 +28,22 @@ class TreeWalker(_base.NonRecursiveTreeWalker):
28
28
to avoid using recursion, returns "nodes" as tuples with the following
29
29
content:
30
30
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)
39
39
"""
40
-
41
- def getNodeDetails (self , node ):
40
+ def getNodeDetails (self , node ):
42
41
if 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 )
46
45
else :
47
- node = elt [ int ( key )]
46
+ node = elt
48
47
49
48
if not (hasattr (node , "tag" )):
50
49
node = node .getroot ()
@@ -61,54 +60,60 @@ def getNodeDetails(self, node):
61
60
else :
62
61
#This is assumed to be an ordinary element
63
62
return _base .ELEMENT , node .tag , node .attrib .items (), len (node ) or node .text
64
-
63
+
65
64
def 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
71
67
else :
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
77
72
else :
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
+
80
81
def getNextSibling (self , node ):
81
82
if 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
93
84
else :
94
85
return 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
100
93
else :
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
+
103
101
def getParentNode (self , node ):
104
102
if 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
111
104
else :
112
105
return 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
113
118
114
119
return locals ()
0 commit comments