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.
Defaults to True.
"""
stanza_ns = '' if top_level_ns else self.namespace
return tostring(self.xml, xmlns='',
stanza_ns=stanza_ns,
top_level=not top_level_ns)
top_level=True)
def __repr__(self):
"""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.
Defaults to ``False``.
"""
stanza_ns = '' if top_level_ns else self.namespace
return tostring(self.xml, xmlns='',
stanza_ns=stanza_ns,
xmlns = self.stream.default_ns if self.stream else ''
return tostring(self.xml, xmlns=xmlns,
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

View file

@ -24,19 +24,18 @@ if sys.version_info < (3, 0):
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):
"""Serialize an XML object to a Unicode string.
If namespaces are provided using ``xmlns`` or ``stanza_ns``, then
elements that use those namespaces will not include the xmlns attribute
in the output.
If an outer xmlns is provided using ``xmlns``, then the current element's
namespace will not be included if it matches the outer namespace. An
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 string xmlns: Optional namespace of an element wrapping the XML
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 string outbuffer: Optional buffer for storing serializations
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.
namespace = ''
if top_level and tag_xmlns not in ['', default_ns, stream_ns] or \
tag_xmlns not in ['', xmlns, stanza_ns, stream_ns]:
if top_level and tag_xmlns not in [default_ns, xmlns, stream_ns] \
or not top_level and tag_xmlns != xmlns:
namespace = ' xmlns="%s"' % tag_xmlns
if stream and tag_xmlns in stream.namespace_map:
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))
if len(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)
elif xml.text:
# If we only have text content.

View file

@ -1244,7 +1244,9 @@ class XMLStream(object):
data = filter(data)
if data is None:
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)
else:
self.send_raw(data, now)

View file

@ -85,19 +85,6 @@ class TestToString(SleekTest):
original='<a>foo <b>bar</b> baz</a>',
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):
"""
Test that stanza objects are serialized properly.