dict->XML->dict? Or, passing small hashes through text?

Fredrik Lundh fredrik at pythonware.com
Fri Aug 15 03:24:10 EDT 2003


"mackstann" wrote:

> I'm thinking that the ideal way that it would happen with XML in the mix
> would be something like:
>
> msg = {}
> msg["foo"] = 1
> msg["bar"] = "hello"
> msg["abc"] = "text"
>
> xmsg = xmlMessage(msg)
>
> xmsg would now be a string such as:
> '<?xml version="1.0"?><foo>1</foo><bar>hello</bar><abc>text</abc></xml>'

(that's not valid XML: there can be only one toplevel element in an
XML document.  that's easy to fix, of course)

> I could then send that over the wire, and on the other end, do something
> like:
>
> msg = xmlMessage2dict(xmsg)
>
> And I'd have my dict back.  I don't think I'll be using values other
> than strings and ints.  Dealing with variable types is something I'm
> unsure of, e.g. making sure that I get back msg["foo"]==1, not
> msg["foo"]=="1".

here's a minimal implementation, based on my ElementTree module:

from elementtree import ElementTree

def xmlMessage(dict):
    elem = ElementTree.Element("message")
    for key, value in dict.items():
        if isinstance(value, type(0)):
            ElementTree.SubElement(elem, key, type="int").text = str(value)
        else:
            ElementTree.SubElement(elem, key).text = value
    return ElementTree.tostring(elem)

def xmlMessage2dict(message):
    elem = ElementTree.XML(message)
    assert elem.tag == "message"
    dict = {}
    for elem in elem:
        if elem.get("type") == "int":
            dict[elem.tag] = int(elem.text)
        else:
            dict[elem.tag] = elem.text
    return dict

msg = {}
msg["foo"] = 1
msg["bar"] = "hello"
msg["abc"] = "text"

xmsg = xmlMessage(msg)

print xmsg
-> <message><bar>hello</bar><abc>text</abc><foo type="int">1</foo></message>

print xmlMessage2dict(xmsg)
-> {'foo': 1, 'bar': 'hello', 'abc': 'text'}


you can get the elementtree source code via this page:

    http://effbot.org/zone/element-index.htm


note that this approach places some limitations on your data; the
keys must all be valid XML names, you must use Unicode strings if
keys or values contain non-ASCII data, you can only use integers
and strings, etc.  tweak as necessary.


if the XML format doesn't really matter, you can use Python's
standard xmlrpclib module:

import xmlrpclib

def xmlMessage(dict):
    # dumps requires a tuple
    return xmlrpclib.dumps((dict,))

def xmlMessage2dict(message):
    result, method = xmlrpclib.loads(message)
    return result[0] # unwrap

</F>

<!-- (the eff-bot guide to) the python standard library (redux):
http://effbot.org/zone/librarybook-index.htm
-->








More information about the Python-list mailing list