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