62 votes

Sérialiser un dictionnaire Python en XML

Il existe un module de sérialisation JSON simple appelé "simplejson" qui sérialise facilement les objets Python en JSON.

Je cherche un module similaire qui puisse sérialiser en XML.

18voto

mdorseif Points 7473

Il y a huTools.structured.dict2xml qui s'efforce d'être compatible avec simplejson en esprit. Vous pouvez lui donner des indications sur la manière d'envelopper des sous-structures imbriquées. Consultez la documentation de huTools.structured.dict2et qui renvoie ElementTree à la place des objets si les chaînes renvoyées par 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>'''

14voto

11voto

nuggetier Points 104

Le seul problème est que je n'utilise pas les attributs (parce que je ne les aime pas).
dict2xml sur pynuggets.wordpress.com
dict2xml sur 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()

9voto

Reimund Points 1292

J'ai écrit une fonction simple qui sérialise les dictionnaires en xml (moins de 30 lignes).

Utilisation :

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

Résultat :

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

La source complète (y compris un exemple) peut être consultée sur le site suivant https://gist.github.com/reimund/5435343/

Nota: Cette fonction sérialise les entrées du dictionnaire sous forme d'attributs plutôt que de nœuds de texte. Il serait très facile de la modifier pour qu'elle prenne en charge le texte.

2voto

rts1 Points 286

La plupart des objets en Python sont représentés sous forme de dicts :

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

Cela revient donc à demander comment convertir des fichiers dicts en XML. Il existe des outils pour convertir les dictées en XML ou inversement :

http://www.picklingtools.com

Voici un exemple simple :

    >>> 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>

Le site web contient de nombreux exemples de documentation :

Manuel des outils XML

Il est difficile de faire une conversion "exacte" entre les listes et XML : Qu'est-ce qu'une liste ? Qu'est-ce qu'une liste ? Qu'est-ce qu'on fait avec les attributs ? Comment gérer les clés numériques ? Un grand nombre de ces questions ont été abordées et sont abordés dans la documentation sur les outils XML (ci-dessus).

La vitesse est-elle importante pour vous ? Ou bien la facilité d'utilisation ? Il existe un module C++ pur (entièrement écrit en C++), un module Python pur (entièrement écrit en Python) et un module Python C Extension (écrit en C++, mais enveloppé de manière à ce que Python puisse l'appeler). Le module C++ et le module Python C Extension sont des ordres de grandeur plus rapides, mais nécessitent bien sûr une compilation pour démarrer. Le module Python devrait fonctionner, mais il est plus lent :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X