Double Possible:
Convertir XML en JSON à l'aide de Python?Je suis en train de faire un travail sur App Engine et j'ai besoin de convertir un document XML être récupéré à partir d'un serveur distant en un équivalent objet JSON.
Je suis à l'aide d'
xml.dom.minidom
pour analyser les données XML retourné parurlfetch
. J'ai également essayé d'utiliserdjango.utils.simplejson
pour convertir l'analyse du document XML en JSON. Je suis tout à fait à une perte quant à comment relier les deux ensemble. Ci-dessous le code que j'en suis à bricoler avec: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)
Réponses
Trop de publicités?xmltodict (divulgation complète: je l'ai écrit) peut vous aider à convertir votre fichier XML dict+liste+la structure de la chaîne, à la suite de cette "norme". Il est Expat, donc il est très rapide et n'a pas besoin de charger la totalité de l'arborescence XML en mémoire.
Une fois que vous avez la structure de données, vous pouvez sérialiser JSON:
import xmltodict, json
o = xmltodict.parse('<e> <a>text</a> <a>text</a> </e>')
json.dumps(o) # '{"e": {"a": ["text", "text"]}}'
Soviut conseils pour lxml objectiver est bon. Spécialement par un sous-classé simplejson, vous pouvez transformer une lxml objectiver résultat 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, par exemple, de l'utilisation, essentiellement, vous transmettre le résultat de lxml objectify
pour l'encodage de la méthode d'une instance de objectJSONEncoder
Notez que Koen point est très valable ici, la solution ci-dessus ne fonctionne que pour simplement xml imbriqués et ne pas inclure le nom de la racine éléments. Ce pourrait être résolu.
J'ai inclus cette classe dans un résumé ici: http://gist.github.com/345559
Je pense que le format XML peut être si diverses qu'il est impossible d'écrire un code qui pourrait faire cela sans un très strictes définies format XML. 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>
Allait devenir
{'persons': [
{'name': 'Koen Bok', 'age': 26},
{'name': 'Plutor Heidepeen', 'age': 33}]
}
Mais ce qui serait-ce:
<persons>
<person name="Koen Bok">
<locations name="defaults">
<location long=123 lat=384 />
</locations>
</person>
</persons>
Voyez ce que je veux dire?
Edit: viens 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 Objectiver ou ElementTree de la lxml module. Une version plus ancienne ElementTree est également disponible dans les python xml.programme etree module ainsi. L'une de ces obtiendrez votre xml convertis à des objets Python que vous pouvez ensuite utiliser simplejson pour sérialiser l'objet JSON.
Tandis que ceci peut sembler comme une douloureuse étape intermédiaire, il commence à faire plus de sens quand vous avez affaire avec XML et normale des objets Python.