1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 """
29 etree Element implementations for use with (multi)parented trees.
30 """
31
32 from xml.etree import ElementTree as ET
33
34 __all__ = ['_ParentedElement', '_MultiParentedElement',
35 'is_parented_element', 'is_multiparented_element']
36
37
38
39
40
42 """
43 An abstract base class for (multi)parented element tree Elements.
44
45 - Whenever a new child is added, L{_setparent} is called,
46 which should update that child's parent pointer to point
47 at self.
48
49 - Whenever a child is removed, L{_delparent} is called, which
50 should remove the child's parent pointer to self.
51 """
53 return "<%s %s at %x>" % (self.__class__.__name__,
54 self.tag, id(self))
55
56
57
58
59
61 """
62 Update C{child}'s parent pointer to point to self.
63 """
64 raise AssertionError, 'Abstract base class'
65
67 """
68 Remove self from C{child}'s parent pointer.
69 """
70 raise AssertionError, 'Abstract base class'
71
72
73
74
75
76
77
81
83 for index in range(start, stop): self._delparent(self[index])
84 ET._ElementInterface.__delslice__(self, start, stop)
85
90
95
99
103
104 - def insert(self, index, element):
105 self._setparent(element)
106 ET._ElementInterface.insert(self, index, element)
107
109 self._delparent(self[-1])
110 return ET._ElementInterface.pop(self, )
111
113 index = self.index(element)
114 self._delparent(self[index])
115 ET._ElementInterface.remove(self, element)
116
117
119 """
120 A specialized version of etree.ElementTree.Element that keeps
121 track of a single parent pointer per element.
122
123 Each _ParentedElement may have at most one parent. In particular,
124 subtrees may not be shared. Any attempt to reuse a single
125 _ParentedElement as a child of more than one parent (or as
126 multiple children of the same parent) will cause a ValueError
127 exception to be raised.
128
129 _ParentedElements should never be used in the same tree as other
130 Element implementation classes. Mixing Element implementations
131 may result in incorrect parent pointers and in C{ValueError}
132 exceptions.
133 """
135 ET._ElementInterface.__init__(self, tag, attrib)
136 self._parent = None
137
140
142 assert is_parented_element(element)
143 if element._parent is not None:
144 raise ValueError, '%r already has a parent' % element
145 element._parent = self
146
148 assert is_parented_element(element)
149 assert element._parent == self
150 element._parent = None
151
154
156 return ET.iselement(element) and hasattr(element, '_parent')
157
159 """
160 A specialized version of etree.ElementTree.Element that keeps
161 track of a list of parent pointers for each element.
162
163 Each _ParentedElement may have zero or more parents. In
164 particular, subtrees may be shared. If a single
165 _MultiParentedElement is used as multiple children of the same
166 parent, then that parent will appear multiple times in the parents
167 list.
168
169 _MultiParentedElements should never be used in the same tree as
170 other Element implementation classes. Mixing Element
171 implementations may result in incorrect parent pointers and in
172 C{ValueError} exceptions.
173 """
175 ET._ElementInterface.__init__(self, tag, attrib)
176 self._parents = []
177
179 return tuple(self._parents)
180
184
189
192
194 return ET.iselement(element) and hasattr(element, '_parents')
195