Add support for using xml:lang values.

Support is only for adding literal XML content
to stanzas. Full support for things like multiple
message bodies with different xml:lang values is
still in the works.
This commit is contained in:
Lance Stout 2010-12-07 23:07:40 -05:00
parent defc252c7d
commit f474d378ef
5 changed files with 41 additions and 8 deletions

View file

@ -116,6 +116,9 @@ class ElementBase(object):
associated plugin stanza classes. associated plugin stanza classes.
plugin_tag_map -- A mapping of plugin stanza tag names with plugin_tag_map -- A mapping of plugin stanza tag names with
the associated plugin stanza classes. the associated plugin stanza classes.
xml_ns -- The XML namespace,
http://www.w3.org/XML/1998/namespace,
for use with xml:lang values.
Instance Attributes: Instance Attributes:
xml -- The stanza's XML contents. xml -- The stanza's XML contents.
@ -144,7 +147,7 @@ class ElementBase(object):
_get_attr -- Return an attribute's value from the main _get_attr -- Return an attribute's value from the main
stanza element. stanza element.
_get_sub_text -- Return the text contents of a subelement. _get_sub_text -- Return the text contents of a subelement.
_set_sub_ext -- Set the text contents of a subelement. _set_sub_text -- Set the text contents of a subelement.
_del_sub -- Remove a subelement. _del_sub -- Remove a subelement.
match -- Compare the stanza against an XPath expression. match -- Compare the stanza against an XPath expression.
find -- Return subelement matching an XPath expression. find -- Return subelement matching an XPath expression.
@ -170,6 +173,7 @@ class ElementBase(object):
plugin_attrib_map = {} plugin_attrib_map = {}
plugin_tag_map = {} plugin_tag_map = {}
subitem = None subitem = None
xml_ns = 'http://www.w3.org/XML/1998/namespace'
def __init__(self, xml=None, parent=None): def __init__(self, xml=None, parent=None):
""" """

View file

@ -52,9 +52,18 @@ def tostring(xml=None, xmlns='', stanza_ns='', stream=None, outbuffer=''):
# Output escaped attribute values. # Output escaped attribute values.
for attrib, value in xml.attrib.items(): for attrib, value in xml.attrib.items():
if '{' not in attrib:
value = xml_escape(value) value = xml_escape(value)
if '}' not in attrib:
output.append(' %s="%s"' % (attrib, value)) output.append(' %s="%s"' % (attrib, value))
else:
attrib_ns = attrib.split('}')[0][1:]
attrib = attrib.split('}')[1]
if stream and attrib_ns in stream.namespace_map:
mapped_ns = stream.namespace_map[attrib_ns]
if mapped_ns:
output.append(' %s:%s="%s"' % (mapped_ns,
attrib,
value))
if len(xml) or xml.text: if len(xml) or xml.text:
# If there are additional child elements to serialize. # If there are additional child elements to serialize.

View file

@ -55,9 +55,18 @@ def tostring(xml=None, xmlns='', stanza_ns='', stream=None, outbuffer=''):
# Output escaped attribute values. # Output escaped attribute values.
for attrib, value in xml.attrib.items(): for attrib, value in xml.attrib.items():
if '{' not in attrib:
value = xml_escape(value) value = xml_escape(value)
output.append(u' %s="%s"' % (attrib, value)) if '}' not in attrib:
output.append(' %s="%s"' % (attrib, value))
else:
attrib_ns = attrib.split('}')[0][1:]
attrib = attrib.split('}')[1]
if stream and attrib_ns in stream.namespace_map:
mapped_ns = stream.namespace_map[attrib_ns]
if mapped_ns:
output.append(' %s:%s="%s"' % (mapped_ns,
attrib,
value))
if len(xml) or xml.text: if len(xml) or xml.text:
# If there are additional child elements to serialize. # If there are additional child elements to serialize.

View file

@ -192,7 +192,7 @@ class XMLStream(object):
self.send_queue = queue.Queue() self.send_queue = queue.Queue()
self.scheduler = Scheduler(self.event_queue, self.stop) self.scheduler = Scheduler(self.event_queue, self.stop)
self.namespace_map = {} self.namespace_map = {StanzaBase.xml_ns: 'xml'}
self.__thread = {} self.__thread = {}
self.__root_stanza = [] self.__root_stanza = []

View file

@ -1,6 +1,6 @@
from sleekxmpp.test import * from sleekxmpp.test import *
from sleekxmpp.stanza import Message from sleekxmpp.stanza import Message
from sleekxmpp.xmlstream.stanzabase import ET from sleekxmpp.xmlstream.stanzabase import ET, ElementBase
from sleekxmpp.xmlstream.tostring import tostring, xml_escape from sleekxmpp.xmlstream.tostring import tostring, xml_escape
@ -110,5 +110,16 @@ class TestToString(SleekTest):
self.failUnless(result == expected, self.failUnless(result == expected,
"Stanza Unicode handling is incorrect: %s" % result) "Stanza Unicode handling is incorrect: %s" % result)
def testXMLLang(self):
"""Test that serializing xml:lang works."""
msg = self.Message()
msg._set_attr('{%s}lang' % msg.xml_ns, "no")
expected = '<message xml:lang="no" />'
result = msg.__str__()
self.failUnless(expected == result,
"Serialization with xml:lang failed: %s" % result)
suite = unittest.TestLoader().loadTestsFromTestCase(TestToString) suite = unittest.TestLoader().loadTestsFromTestCase(TestToString)