Duplicata possible:
Conversion de XML en JSON en utilisant Python?
Je travaille sur App Engine et j'ai besoin de convertir un document XML récupéré d'un serveur distant en un objet JSON équivalent.
J'utilise xml.dom.minidom
pour analyser les données XML renvoyées par urlfetch
. J'essaie également d'utiliser Django.utils.simplejson
pour convertir le document XML analysé en JSON. Je ne sais vraiment pas comment lier les deux ensemble. Voici le code avec lequel je bricoler:
from xml.dom import minidom
from Django.utils import simplejson as json
#pseudo code that returns actual xml data as a string from remote server.
result = urlfetch.fetch(url,'','get');
dom = minidom.parseString(result.content)
json = simplejson.load(dom)
self.response.out.write(json)
Les conseils de Soviut pour objectiver lxml sont bons. Avec un simplejson spécialement sous-classé, vous pouvez transformer un résultat d'objectivation lxml en json.
import simplejson as json
import lxml
class objectJSONEncoder(json.JSONEncoder):
"""A specialized JSON encoder that can handle simple lxml objectify types
>>> from lxml import objectify
>>> obj = objectify.fromstring("<Book><price>1.50</price><author>W. Shakespeare</author></Book>")
>>> objectJSONEncoder().encode(obj)
'{"price": 1.5, "author": "W. Shakespeare"}'
"""
def default(self,o):
if isinstance(o, lxml.objectify.IntElement):
return int(o)
if isinstance(o, lxml.objectify.NumberElement) or isinstance(o, lxml.objectify.FloatElement):
return float(o)
if isinstance(o, lxml.objectify.ObjectifiedDataElement):
return str(o)
if hasattr(o, '__dict__'):
#For objects with a __dict__, return the encoding of the __dict__
return o.__dict__
return json.JSONEncoder.default(self, o)
Voir la docstring pour un exemple d'utilisation, essentiellement vous passez le résultat de lxml objectify
à la méthode d'encode d'une instance de objectJSONEncoder
Notez que le point de Koen est très valide ici, la solution ci-dessus ne fonctionne que pour le xml simplement imbriqué et n'inclut pas le nom des éléments racine. Cela pourrait être corrigé.
J'ai inclus cette classe dans un Gist ici: http://Gist.github.com/345559
xmltodict (divulgation complète: je l'ai écrit) peut vous aider à convertir votre XML en une structure dict + list + string, en suivant ceci "standard" . Il est basé sur Expat , il est donc très rapide et n'a pas besoin de charger la totalité de l'arborescence XML en mémoire.
Une fois que vous avez cette structure de données, vous pouvez la sérialiser en JSON:
import xmltodict, json
o = xmltodict.parse('<e> <a>text</a> <a>text</a> </e>')
json.dumps(o) # '{"e": {"a": ["text", "text"]}}'
Je pense que le format XML peut être si diversifié qu'il est impossible d'écrire un code qui pourrait le faire sans un format XML défini très strict. Voici ce que je veux dire:
<persons>
<person>
<name>Koen Bok</name>
<age>26</age>
</person>
<person>
<name>Plutor Heidepeen</name>
<age>33</age>
</person>
</persons>
Deviendrait
{'persons': [
{'name': 'Koen Bok', 'age': 26},
{'name': 'Plutor Heidepeen', 'age': 33}]
}
Mais que serait-ce:
<persons>
<person name="Koen Bok">
<locations name="defaults">
<location long=123 lat=384 />
</locations>
</person>
</persons>
Tu vois ce que je veux dire?
Edit: vient de trouver cet article: http://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html
Jacob Smullyan a écrit un utilitaire appelé pesterfish qui utilise ElementTree d'effbot pour convertir XML en JSON.
Une possibilité serait d'utiliser Objectify ou ElementTree à partir du module lxml . Une ancienne version ElementTree est également disponible dans le module python xml.etree également. L'un ou l'autre de ces éléments convertira votre xml en Python objets que vous pourrez ensuite utilisez simplejson pour sérialiser l'objet en JSON.
Bien que cela puisse sembler une étape intermédiaire douloureuse, cela commence à avoir plus de sens lorsque vous traitez à la fois avec XML et normal Python objets.
J'ai écrit une petite ligne de commande basée sur Python basé sur pesterfesh qui fait exactement ceci:
En général, vous voulez passer du XML aux objets réguliers de votre langage (car il existe généralement des outils raisonnables pour le faire, et c'est la conversion la plus difficile). Et puis à partir de Plain Old Object produire JSON - il y a aussi des outils pour cela, et c'est une sérialisation assez simple (puisque JSON est "Object Notation", naturel pour la sérialisation d'objets). Je suppose que Python a son ensemble d'outils.