62 votos

Serializar diccionario de Python para XML

No es simple serialización JSON módulo con el nombre "simplejson" que fácilmente se serializa los objetos de Python para JSON.

Estoy buscando similares módulo en el cual se puede serializar a XML.

18voto

mdorseif Puntos 7473

Hay huTools.structured.dict2xml que intenta ser compatible a simplejson en el espíritu. Que se le puede dar sugerencias de cómo envolver anidada sub-estructuras. Consulte la documentación de huTools.structured.dict2et que devuelve ElementTree Objetos en su lugar si las cadenas devuelto por 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 Puntos 104

probar este. el único problema que yo no uso atributos (porque no me gustan)
dict2xml en pynuggets.wordpress.com
dict2xml en 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 Puntos 1292

Escribí una simple función que serializa los diccionarios para xml (menores de 30 líneas).

Uso:

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

Resultado:

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

El código fuente completo (incluyendo un ejemplo) se puede encontrar en https://gist.github.com/reimund/5435343/

Nota: Esta función serialize entradas del diccionario como los atributos de los nodos de texto. Modificación de la misma para apoyar el texto sería muy fácil.

2voto

rts1 Puntos 286

La mayoría de los objetos en Python son representados como dicts debajo:

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

Así que esto es similar a la pregunta ¿cómo convertir dicts a XML. Existen herramientas para la conversión de dict a/desde XML en:

http://www.picklingtools.com

He aquí un ejemplo sencillo:

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

Hay un montón de documentación en el sitio web mostrando ejemplos:

Herramientas de XML Manual

Es difícil convertir "exactamente" entre dicts y XML: ¿Qué es una lista? ¿Qué hacer con los atributos? ¿Cómo manejar las teclas numéricas? Muchos de estos problemas han sido abordados y se discuten en el XML de la documentación de las herramientas (arriba).

Qué velocidad te importa? O la facilidad de uso? No es un puro módulo de C++ (todo escrito en C++), un puro módulo de Python (todo escrito en Python), y una de Python C módulo de Extensión (escrito en C++, pero envuelto de modo que Python puede llamar). El C++ y Python C módulo de Extensión son órdenes de magnitud más rápido, pero por supuesto, requieren compilar para ponerse en marcha. El módulo de Python debería funcionar, pero es más lento:

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X