Serialize Python dictionary to XML [closed]
Asked Answered
C

5

65

There is simple JSON serialization module with name "simplejson" which easily serializes Python objects to JSON.

I'm looking for similar module which can serialize to XML.

Chronic answered 19/6, 2009 at 20:26 Comment(0)
I
15

http://code.activestate.com/recipes/415983/

http://sourceforge.net/projects/pyxser/

http://soapy.sourceforge.net/

http://www.ibm.com/developerworks/webservices/library/ws-pyth5/

http://gnosis.cx/publish/programming/xml_matters_1.txt

Imputable answered 19/6, 2009 at 20:29 Comment(3)
> code.activestate.com/recipes/415983 This one doesn't serialize to XML only to marshal format. And also I don't like sys.exit on Exception. > sourceforge.net/projects/pyxser This one is not BSD. Sorry I forgot to mention, I'm looking for python module or BSD, so I can distribute with my BSD software. The last 2 - for webservices, I'm looking for regular XML serializator.Chronic
zdmytriv: you can distribute a LGPL library with your BSD code without liabilities.Seen
@nosklo: I didn't know that you can do that. Now I know, thanks.Chronic
G
18

There is huTools.structured.dict2xml which tries to be compatible to simplejson in spirit. You can give it hints how to wrap nested sub-structures. Check the documentation for huTools.structured.dict2et which returns ElementTree Objects instead if the strings returned by dict2xml.

>>> data = {"kommiauftragsnr":2103839, "anliefertermin":"2009-11-25", "prioritaet": 7,
... "ort": u"Hücksenwagen",
... "positionen": [{"menge": 12, "artnr": "14640/XL", "posnr": 1},],
... "versandeinweisungen": [{"guid": "2103839-XalE", "bezeichner": "avisierung48h",
...                          "anweisung": "48h vor Anlieferung unter 0900-LOGISTIK avisieren"},
... ]}

>>> print ET.tostring(dict2et(data, 'kommiauftrag',
... listnames={'positionen': 'position', 'versandeinweisungen': 'versandeinweisung'}))
'''<kommiauftrag>
<anliefertermin>2009-11-25</anliefertermin>
<positionen>
    <position>
        <posnr>1</posnr>
        <menge>12</menge>
        <artnr>14640/XL</artnr>
    </position>
</positionen>
<ort>H&#xC3;&#xBC;cksenwagen</ort>
<versandeinweisungen>
    <versandeinweisung>
        <bezeichner>avisierung48h</bezeichner>
        <anweisung>48h vor Anlieferung unter 0900-LOGISTIK avisieren</anweisung>
        <guid>2103839-XalE</guid>
    </versandeinweisung>
</versandeinweisungen>
<prioritaet>7</prioritaet>
<kommiauftragsnr>2103839</kommiauftragsnr>
</kommiauftrag>'''
Genotype answered 22/11, 2010 at 7:40 Comment(2)
huTools is not compatible with Python 3 ('dict' object has no attribute 'iteritems').Beaker
What are the licensing terms of this thing? Can I use it my commercial app?Meteorite
I
15

http://code.activestate.com/recipes/415983/

http://sourceforge.net/projects/pyxser/

http://soapy.sourceforge.net/

http://www.ibm.com/developerworks/webservices/library/ws-pyth5/

http://gnosis.cx/publish/programming/xml_matters_1.txt

Imputable answered 19/6, 2009 at 20:29 Comment(3)
> code.activestate.com/recipes/415983 This one doesn't serialize to XML only to marshal format. And also I don't like sys.exit on Exception. > sourceforge.net/projects/pyxser This one is not BSD. Sorry I forgot to mention, I'm looking for python module or BSD, so I can distribute with my BSD software. The last 2 - for webservices, I'm looking for regular XML serializator.Chronic
zdmytriv: you can distribute a LGPL library with your BSD code without liabilities.Seen
@nosklo: I didn't know that you can do that. Now I know, thanks.Chronic
G
12

try this one. only problem I don't use attributes (because i dont like them)
dict2xml on pynuggets.wordpress.com
dict2xml on activestate

from xml.dom.minidom import Document
import copy

class dict2xml(object):
    doc     = Document()

    def __init__(self, structure):
        if len(structure) == 1:
            rootName    = str(structure.keys()[0])
            self.root   = self.doc.createElement(rootName)

            self.doc.appendChild(self.root)
            self.build(self.root, structure[rootName])

    def build(self, father, structure):
        if type(structure) == dict:
            for k in structure:
                tag = self.doc.createElement(k)
                father.appendChild(tag)
                self.build(tag, structure[k])

        elif type(structure) == list:
            grandFather = father.parentNode
            tagName     = father.tagName
            grandFather.removeChild(father)
            for l in structure:
                tag = self.doc.createElement(tagName)
                self.build(tag, l)
                grandFather.appendChild(tag)

        else:
            data    = str(structure)
            tag     = self.doc.createTextNode(data)
            father.appendChild(tag)

    def display(self):
        print self.doc.toprettyxml(indent="  ")

if __name__ == '__main__':
    example = {'auftrag':{"kommiauftragsnr":2103839, "anliefertermin":"2009-11-25", "prioritaet": 7,"ort": u"Huecksenwagen","positionen": [{"menge": 12, "artnr": "14640/XL", "posnr": 1},],"versandeinweisungen": [{"guid": "2103839-XalE", "bezeichner": "avisierung48h","anweisung": "48h vor Anlieferung unter 0900-LOGISTIK avisieren"},]}}
    xml = dict2xml(example)
    xml.display()
Gamb answered 7/6, 2011 at 8:45 Comment(1)
Here is some problem with creating another instance of dict2xml xml.dom.HierarchyRequestErr: two document elements disallowed, so I added unlink method: def unlink(self): self.doc.unlink()Fiftyfifty
T
10

I wrote a simple function that serializes dictionaries to xml (under 30 lines).

Usage:

mydict = {
    'name': 'The Andersson\'s',
    'size': 4,
    'children': {
        'total-age': 62,
        'child': [
            {
                'name': 'Tom',
                'sex': 'male',
            },
            {
                'name': 'Betty',
                'sex': 'female',
            }
        ]
    },
}
print(dict2xml(mydict, 'family'))

Result:

<family name="The Andersson's" size="4">
        <children total-age="62">
                <child name="Tom" sex="male"/>
                <child name="Betty" sex="female"/>
        </children>
</family>

The full source (including an example) can be found on https://gist.github.com/reimund/5435343/

Note: This function will serialize dictionary entries as attributes rather than text nodes. Modifying it to support text would be very easy.

Tammara answered 22/4, 2013 at 14:13 Comment(0)
O
2

Most objects in Python are represented as dicts underneath:

>>> class Fred(object) : 
...    def __init__(self, n) : self.n = n 
... 
>>> a = Fred(100)
>>> print a.__dict__ 
{'n': 100}

So this is similar to asking how to convert dicts to XML. There are tools for converting dict to/from XML at:

http://www.picklingtools.com

Here is a simple example:

    >>> import xmltools

    >>> d = {'a':1, 'b':2.2, 'c':'three' }
    >>> xx = xmltools.WriteToXMLString(d)
    >>> print xx
    <?xml version="1.0" encoding="UTF-8"?>
    <top>
      <a>1</a>
      <b>2.2</b>
      <c>three</c>
    </top>

There is a lot of documentation at the web site showing examples:

XML Tools Manual

It is difficult to convert "exactly" between dicts and XML: What is a list? What do you do with attributes? How do you handle numeric keys? A lot of these issues have been addressed and are discussed in the XML tools documentation (above).

Does speed matter to you? Or does ease of use matter? There is a pure C++ module (all written in C++), a pure Python module (all written in Python), and a Python C Extension module (written in C++, but wrapped so Python can call it). The C++ and the Python C Extension module are orders of magnitude faster, but of course require compiling to get going. The Python module should just work, but is slower:

Oehsen answered 28/11, 2012 at 15:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.