Simplify stringifying XML

This commit is contained in:
Lance Stout 2012-09-24 20:59:51 -07:00
parent c2ae1ee891
commit 6c57bb0553
4 changed files with 15 additions and 30 deletions

View file

@ -1400,10 +1400,8 @@ class ElementBase(object):
:param bool top_level_ns: Display the top-most namespace. :param bool top_level_ns: Display the top-most namespace.
Defaults to True. Defaults to True.
""" """
stanza_ns = '' if top_level_ns else self.namespace
return tostring(self.xml, xmlns='', return tostring(self.xml, xmlns='',
stanza_ns=stanza_ns, top_level=True)
top_level=not top_level_ns)
def __repr__(self): def __repr__(self):
"""Use the stanza's serialized XML as its representation.""" """Use the stanza's serialized XML as its representation."""
@ -1592,11 +1590,10 @@ class StanzaBase(ElementBase):
:param bool top_level_ns: Display the top-most namespace. :param bool top_level_ns: Display the top-most namespace.
Defaults to ``False``. Defaults to ``False``.
""" """
stanza_ns = '' if top_level_ns else self.namespace xmlns = self.stream.default_ns if self.stream else ''
return tostring(self.xml, xmlns='', return tostring(self.xml, xmlns=xmlns,
stanza_ns=stanza_ns,
stream=self.stream, stream=self.stream,
top_level=not top_level_ns) top_level=(self.stream is None))
#: A JSON/dictionary version of the XML content exposed through #: A JSON/dictionary version of the XML content exposed through

View file

@ -24,19 +24,18 @@ if sys.version_info < (3, 0):
XML_NS = 'http://www.w3.org/XML/1998/namespace' XML_NS = 'http://www.w3.org/XML/1998/namespace'
def tostring(xml=None, xmlns='', stanza_ns='', stream=None, def tostring(xml=None, xmlns='', stream=None,
outbuffer='', top_level=False, open_only=False): outbuffer='', top_level=False, open_only=False):
"""Serialize an XML object to a Unicode string. """Serialize an XML object to a Unicode string.
If namespaces are provided using ``xmlns`` or ``stanza_ns``, then If an outer xmlns is provided using ``xmlns``, then the current element's
elements that use those namespaces will not include the xmlns attribute namespace will not be included if it matches the outer namespace. An
in the output. exception is made for elements that have an attached stream, and appear
at the stream root.
:param XML xml: The XML object to serialize. :param XML xml: The XML object to serialize.
:param string xmlns: Optional namespace of an element wrapping the XML :param string xmlns: Optional namespace of an element wrapping the XML
object. object.
:param string stanza_ns: The namespace of the stanza object that contains
the XML object.
:param stream: The XML stream that generated the XML object. :param stream: The XML stream that generated the XML object.
:param string outbuffer: Optional buffer for storing serializations :param string outbuffer: Optional buffer for storing serializations
during recursive calls. during recursive calls.
@ -71,8 +70,8 @@ def tostring(xml=None, xmlns='', stanza_ns='', stream=None,
# Output the tag name and derived namespace of the element. # Output the tag name and derived namespace of the element.
namespace = '' namespace = ''
if top_level and tag_xmlns not in ['', default_ns, stream_ns] or \ if top_level and tag_xmlns not in [default_ns, xmlns, stream_ns] \
tag_xmlns not in ['', xmlns, stanza_ns, stream_ns]: or not top_level and tag_xmlns != xmlns:
namespace = ' xmlns="%s"' % tag_xmlns namespace = ' xmlns="%s"' % tag_xmlns
if stream and tag_xmlns in stream.namespace_map: if stream and tag_xmlns in stream.namespace_map:
mapped_namespace = stream.namespace_map[tag_xmlns] mapped_namespace = stream.namespace_map[tag_xmlns]
@ -110,7 +109,7 @@ def tostring(xml=None, xmlns='', stanza_ns='', stream=None,
output.append(escape(xml.text, use_cdata)) output.append(escape(xml.text, use_cdata))
if len(xml): if len(xml):
for child in xml: for child in xml:
output.append(tostring(child, tag_xmlns, stanza_ns, stream)) output.append(tostring(child, tag_xmlns, stream))
output.append("</%s>" % tag_name) output.append("</%s>" % tag_name)
elif xml.text: elif xml.text:
# If we only have text content. # If we only have text content.

View file

@ -1244,7 +1244,9 @@ class XMLStream(object):
data = filter(data) data = filter(data)
if data is None: if data is None:
return return
str_data = str(data) str_data = tostring(data.xml, xmlns=self.default_ns,
stream=self,
top_level=True)
self.send_raw(str_data, now) self.send_raw(str_data, now)
else: else:
self.send_raw(data, now) self.send_raw(data, now)

View file

@ -85,19 +85,6 @@ class TestToString(SleekTest):
original='<a>foo <b>bar</b> baz</a>', original='<a>foo <b>bar</b> baz</a>',
message='Element tail content is incorrect.') message='Element tail content is incorrect.')
def testStanzaNs(self):
"""
Test using the stanza_ns tostring parameter, which will prevent
adding an xmlns attribute to the serialized element if the
element's namespace is the same.
"""
self.tryTostring(
original='<bar xmlns="foo" />',
expected='<bar />',
message="The stanza_ns parameter was not used properly.",
stanza_ns='foo')
def testStanzaStr(self): def testStanzaStr(self):
""" """
Test that stanza objects are serialized properly. Test that stanza objects are serialized properly.