XML dict anyone ?

I wanted to be able to persist a Python dictionary (dict, essentially a Map in the Java world) into a string form, and be able to reload it later from the XML and make some sense out of it.

Here’s a very simple example on how you can achieve this very easily.

from xml.dom import minidom
from StringIO import StringIO

VALUE_ATTR = 'value'
class XmlDict(dict):
    def __init__(self, keyToXml, keyFromXml, valueToXml, valueFromXml):
        dict.__init__(self)
        self.keyToXml = keyToXml
        self.keyFromXml = keyFromXml
        self.valueToXml = valueToXml
        self.valueFromXml = valueFromXml

    def fromXml(self, xml):
        self.clear()
        doc = minidom.parseString(xml)
        root = doc.documentElement
        for child in root.childNodes:
            valueBuffer = StringIO()
            for cn in child.childNodes:
                valueBuffer.write(cn.data)
            self[self.keyFromXml(child.tagName)] = self.valueFromXml(valueBuffer.getvalue())

    def toXml(self):
        doc = minidom.getDOMImplementation().createDocument(None, 'dict', None)
        for key, value in self.iteritems():
            wordElement = doc.createElement(self.keyToXml(key))
            valueNode = doc.createTextNode(self.valueToXml(value))
            wordElement.appendChild(valueNode)
            doc.documentElement.appendChild(wordElement)
        return doc.toxml()

The example below basically maps a string to a string:

    d = XmlDict(str, str, str, str)
    d['sds'] = 'ssds'
    d['sdss'] = 'asda'
    print d.toXml()
    d2 = XmlDict(str, str, str, str)
    d2.fromXml(d.toXml())
    print d2

Output is:

<?xml version="1.0" ?><dict><sdss>asda</sdss><sds>ssds</sds></dict>
{'sdss': 'asda', 'sds': 'ssds'}

All you have to do is define your own callable that can take in a keys/values and convert them into string representations.

Infact, by having smarter callables that check the value being persisted, you could runaway with chucking anything into the string value (nested XML in attributes is wrong though and should really be avoided)

Tags: ,

Leave a Reply