summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sleekxmpp/xmlstream/stanzabase.py46
-rw-r--r--tests/test_elementbase.py34
2 files changed, 71 insertions, 9 deletions
diff --git a/sleekxmpp/xmlstream/stanzabase.py b/sleekxmpp/xmlstream/stanzabase.py
index 7458f3c7..75b9b921 100644
--- a/sleekxmpp/xmlstream/stanzabase.py
+++ b/sleekxmpp/xmlstream/stanzabase.py
@@ -354,6 +354,26 @@ class ElementBase(object):
"""
return self.xml.attrib.get(name, default)
+ def _getSubText(self, name, default=''):
+ """
+ Return the text contents of a sub element.
+
+ In case the element does not exist, or it has no textual content,
+ a default value can be returned instead. An empty string is returned
+ if no other default is supplied.
+
+ Arguments:
+ name -- The name or XPath expression of the element.
+ default -- Optional default to return if the element does
+ not exists. An empty string is returned otherwise.
+ """
+ name = self._fix_ns(name)
+ stanza = self.xml.find(name)
+ if stanza is None or stanza.text is None:
+ return default
+ else:
+ return stanza.text
+
@property
def attrib(self): #backwards compatibility
return self
@@ -449,15 +469,6 @@ class ElementBase(object):
return False
return True
- def _getSubText(self, name):
- if '}' not in name:
- name = "{%s}%s" % (self.namespace, name)
- stanza = self.xml.find(name)
- if stanza is None or stanza.text is None:
- return ''
- else:
- return stanza.text
-
def _setSubText(self, name, attrib={}, text=None):
if '}' not in name:
name = "{%s}%s" % (self.namespace, name)
@@ -490,6 +501,23 @@ class ElementBase(object):
def __repr__(self):
return self.__str__()
+ def _fix_ns(self, xpath):
+ """
+ Apply the stanza's namespace to elements in an XPath expression.
+
+ Arguments:
+ xpath -- The XPath expression to fix with namespaces.
+ """
+
+ def fix_ns(name):
+ """Apply namespace to an element if needed."""
+ if "}" in name:
+ return name
+ return "{%s}%s" % (self.namespace, name)
+
+ return "/".join(map(fix_ns, xpath.split("/")))
+
+
#def __del__(self): #prevents garbage collection of reference cycle
# if self.parent is not None:
# self.parent.xml.remove(self.xml)
diff --git a/tests/test_elementbase.py b/tests/test_elementbase.py
index 78277af4..78cf47d6 100644
--- a/tests/test_elementbase.py
+++ b/tests/test_elementbase.py
@@ -267,5 +267,39 @@ class TestElementBase(SleekTest):
self.failUnless(stanza._getAttr('bar', 'c') == 'c',
"Incorrect default value returned for an unset XML attribute.")
+
+ def testGetSubText(self):
+ """Test retrieving the contents of a sub element."""
+
+ class TestStanza(ElementBase):
+ name = "foo"
+ namespace = "foo"
+ interfaces = set(('bar',))
+
+ def setBar(self, value):
+ wrapper = ET.Element("{foo}wrapper")
+ bar = ET.Element("{foo}bar")
+ bar.text = value
+ wrapper.append(bar)
+ self.xml.append(wrapper)
+
+ def getBar(self):
+ return self._getSubText("wrapper/bar", default="not found")
+
+ stanza = TestStanza()
+ self.failUnless(stanza['bar'] == 'not found',
+ "Default _getSubText value incorrect.")
+
+ stanza['bar'] = 'found'
+ self.checkStanza(TestStanza, stanza, """
+ <foo xmlns="foo">
+ <wrapper>
+ <bar>found</bar>
+ </wrapper>
+ </foo>
+ """)
+ self.failUnless(stanza['bar'] == 'found',
+ "_getSubText value incorrect: %s." % stanza['bar'])
+
suite = unittest.TestLoader().loadTestsFromTestCase(TestElementBase)