Updated ElementBase._getSubText and added unit tests.

Also added ElementBase._fix_ns() to apply the stanza namespace to elements that don't have a namespace.
This commit is contained in:
Lance Stout 2010-08-24 08:55:37 -04:00
parent f4ecf0bac4
commit 203986dd7c
2 changed files with 71 additions and 9 deletions

View file

@ -354,6 +354,26 @@ class ElementBase(object):
""" """
return self.xml.attrib.get(name, default) 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 @property
def attrib(self): #backwards compatibility def attrib(self): #backwards compatibility
return self return self
@ -449,15 +469,6 @@ class ElementBase(object):
return False return False
return True 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): def _setSubText(self, name, attrib={}, text=None):
if '}' not in name: if '}' not in name:
name = "{%s}%s" % (self.namespace, name) name = "{%s}%s" % (self.namespace, name)
@ -490,6 +501,23 @@ class ElementBase(object):
def __repr__(self): def __repr__(self):
return self.__str__() 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 #def __del__(self): #prevents garbage collection of reference cycle
# if self.parent is not None: # if self.parent is not None:
# self.parent.xml.remove(self.xml) # self.parent.xml.remove(self.xml)

View file

@ -268,4 +268,38 @@ class TestElementBase(SleekTest):
self.failUnless(stanza._getAttr('bar', 'c') == 'c', self.failUnless(stanza._getAttr('bar', 'c') == 'c',
"Incorrect default value returned for an unset XML attribute.") "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) suite = unittest.TestLoader().loadTestsFromTestCase(TestElementBase)