web-dev-qa-db-fra.com

Sérialiser Python en XML

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

Je recherche un module similaire qui peut sérialiser en XML.

62
zinovii
14
S.Lott

Il y a huTools.structured.dict2xml qui essaie d'être compatible avec simplejson dans l'esprit. Vous pouvez lui donner des astuces pour envelopper des sous-structures imbriquées. Consultez la documentation pour huTools.structured.dict2et qui renvoie ElementTree Objets à la place si les chaînes retourné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>'''
18
max

essaye celui-là. seul problème je n'utilise pas d'attributs (car 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 __== '__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()
11
nuggetier

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

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

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 trouvée sur https://Gist.github.com/reimund/5435343/

Remarque: Cette fonction sérialise les entrées du dictionnaire sous forme d'attributs plutôt que de nœuds de texte. Le modifier pour prendre en charge le texte serait très facile.

9
Reimund

La plupart des objets dans Python sont représentés sous forme de dict en dessous:

>>> 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 dict en XML. Il existe des outils pour convertir dict vers/depuis XML sur:

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>

Il y a beaucoup de documentation sur le site Web montrant des exemples:

Manuel des outils XML

Il est difficile de convertir "exactement" entre dict et XML: qu'est-ce qu'une liste? Que faites-vous avec les attributs? Comment gérez-vous les touches numériques? Un grand nombre de ces problèmes ont été résolus et sont abordés dans la documentation des outils XML (ci-dessus).

La vitesse est-elle importante pour vous? Ou la facilité d'utilisation est-elle importante? Il existe un module C++ pur (tous écrits en C++), un module Python pur (tous écrits en Python), et un module Python C Extension C (écrit en C++, mais encapsulé donc Python peut l'appeler). Le C++ et le module d'extension C Python C sont des ordres de grandeur plus rapides, mais nécessitent bien sûr une compilation en Le module Python devrait fonctionner, mais est plus lent:

2
rts1