diff options
author | Lance Stout <lstout@kestrel.cs.clemson.edu> | 2010-08-25 10:52:07 -0400 |
---|---|---|
committer | Lance Stout <lstout@kestrel.cs.clemson.edu> | 2010-08-25 10:52:07 -0400 |
commit | 5d458bf6c2fae32d659b29ac2697a20b781bfbd0 (patch) | |
tree | ed422e8581565e2ab3608c118877409b9e1b3d41 /sleekxmpp | |
parent | 2fa58a74ab2d9f5f84edc036ea89f0b203e3f7e9 (diff) | |
download | slixmpp-5d458bf6c2fae32d659b29ac2697a20b781bfbd0.tar.gz slixmpp-5d458bf6c2fae32d659b29ac2697a20b781bfbd0.tar.bz2 slixmpp-5d458bf6c2fae32d659b29ac2697a20b781bfbd0.tar.xz slixmpp-5d458bf6c2fae32d659b29ac2697a20b781bfbd0.zip |
Updated ElementBase._delSub and added unit tests.
_delSub can now accept a path and will optionally remove any empty parent elements after deleting the target elements.
Diffstat (limited to 'sleekxmpp')
-rw-r--r-- | sleekxmpp/xmlstream/stanzabase.py | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/sleekxmpp/xmlstream/stanzabase.py b/sleekxmpp/xmlstream/stanzabase.py index bccb1fb0..22853a9d 100644 --- a/sleekxmpp/xmlstream/stanzabase.py +++ b/sleekxmpp/xmlstream/stanzabase.py @@ -417,6 +417,44 @@ class ElementBase(object): element.text = text return element + def _delSub(self, name, all=False): + """ + Remove sub elements that match the given name or XPath. + + If the element is in a path, then any parent elements that become + empty after deleting the element may also be deleted if requested + by setting all=True. + + Arguments: + name -- The name or XPath expression for the element(s) to remove. + all -- If True, remove all empty elements in the path to the + deleted element. Defaults to False. + """ + name = self._fix_ns(name) + path = name.split("/") + original_target = path[-1] + + for level, _ in enumerate(path): + # Generate the paths to the target elements and their parent. + element_path = "/".join(path[:len(path) - level]) + parent_path = "/".join(path[:len(path) - level - 1]) + + elements = self.xml.findall(element_path) + parent = self.xml.find(parent_path) + + if elements: + if parent is None: + parent = self.xml + for element in elements: + if element.tag == original_target or not element.getchildren(): + # Only delete the originally requested elements, and any + # parent elements that have become empty. + parent.remove(element) + if not all: + # If we don't want to delete elements up the tree, stop + # after deleting the first level of elements. + return + @property def attrib(self): #backwards compatibility return self @@ -512,13 +550,6 @@ class ElementBase(object): return False return True - def _delSub(self, name): - if '}' not in name: - name = "{%s}%s" % (self.namespace, name) - for child in self.xml.getchildren(): - if child.tag == name: - self.xml.remove(child) - def appendxml(self, xml): self.xml.append(xml) return self |