Как преобразовать XML в JSON в Python?

Possible Duplicate:
Converting XML to JSON using Python?

Я работаю над App Engine, и мне нужно преобразовать XML-документ, полученный с удаленного сервера, в эквивалентный объект JSON.

Я использую xml.dom.minidom для анализа XML-данных, возвращаемых urlfetch. Я также пытаюсь использовать django.utils.simplejson для преобразования проанализированного XML-документа в JSON. Я совершенно не понимаю, как связать их вместе. Ниже приведен код, над которым я работаю:

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)

Ранее: stackoverflow.com/questions/191536/…

RexE 23.01.2009 10:44

взгляните на это: github.com/aausch/filteringxmljsonifier

blueberryfields 13.11.2014 04:50
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
64
2
107 256
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Джейкоб Смуллян написал утилиту под названием ядовитая рыба, которая использует ЭлементДерево effbot для преобразования XML в JSON.

Установка с помощью pip кажется неработающей: UnicodeDecodeError: 'utf8' codec can't decode byte 0x8b in position 1: invalid start byte

smci 19.08.2014 18:55

Я думаю, что формат XML может быть настолько разнообразным, что невозможно написать код, который мог бы это сделать, без очень строго определенного формата XML. Вот что я имею в виду:

<persons>
    <person>
        <name>Koen Bok</name>
        <age>26</age>
    </person>
    <person>
        <name>Plutor Heidepeen</name>
        <age>33</age>
    </person>
</persons>

Станет

{'persons': [
    {'name': 'Koen Bok', 'age': 26},
    {'name': 'Plutor Heidepeen', 'age': 33}]
}

Но что бы это было:

<persons>
    <person name = "Koen Bok">
        <locations name = "defaults">
            <location long=123 lat=384 />
        </locations>
    </person>
</persons>

Понимаете, что я имею в виду?

Обновлено: только что нашел эту статью: http://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html

найденная вами статья предназначена для javascript

George Godik 19.01.2010 23:33

@George Статья посвящена общим вопросам двусторонней передачи XML и JSON. Это очень уместно по этой теме. Не позволяйте коду JavaScript в конце сбить вас с толку.

zigg 02.05.2012 23:29

@ Коэн, будет так. {"people": {"person": {"-name": "Koen Bok", "locations": {"-name": "defaults", "location": {"-long": "123", " -lat ":" 384 "}}}}}

Hugo Prudente 09.03.2016 16:02

Одна из возможностей - использовать Objectify или ElementTree из lxml модуль. Более старая версия ElementTree также доступна в модуле python xml.etree. Любой из них преобразует ваш xml в объекты Python, которые затем можно использовать simplejson для сериализации объекта в JSON.

Хотя это может показаться болезненным промежуточным этапом, он становится более понятным, когда вы имеете дело с обоими обычными объектами Python XML а также.

В общем, вы хотите перейти от XML к обычным объектам вашего языка (поскольку для этого обычно есть разумные инструменты, а это более сложное преобразование). А затем из Plain Old Object создайте JSON - для этого тоже есть инструменты, и это довольно простая сериализация (поскольку JSON - это «нотация объектов», естественно, подходит для сериализации объектов). Я предполагаю, что у Python есть свой набор инструментов.

Ответ принят как подходящий

Совет Совьюта по объективации lxml хорош. С помощью специального подкласса simplejson вы можете превратить результат lxml objectify в 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)

См. Пример использования в строке документации, по сути, вы передаете результат lxml objectify методу кодирования экземпляра objectJSONEncoder.

Обратите внимание, что здесь очень актуальна точка зрения Коэна, приведенное выше решение работает только для простого вложенного xml и не включает имя корневых элементов. Это можно исправить.

Я включил этот класс в суть здесь: http://gist.github.com/345559

Что делать, если у меня есть тег, у которого есть несколько дочерних элементов с одинаковым именем тега?

vittore 08.04.2014 20:28

@vittore: вы можете заменить return o.__dict__ на return [i.__dict__ for i in o] выше, чтобы обрабатывать несколько дочерних элементов.

weaver 15.10.2014 01:39

@weaver, это почти именно то, что я сделал.

vittore 16.10.2014 04:28

Я написал небольшой скрипт Python на основе командной строки, основанный на pesterfesh, который делает именно это:

https://github.com/hay/xml2json

Эта ссылка не работает. Было бы неплохо, если бы его обновили (если скрипт еще существует).

Alison R. 06.04.2011 23:18

Woops, я переместил скрипт в его собственный репозиторий. Спасибо, что обратили внимание на 404!

Husky 07.04.2011 02:25

Спасибо, это прекрасно. Следует отметить, что для установки требуется simplejson: sudo easy_install simplejson

Suman 13.04.2012 01:30

@ srs2012 Я не пробовал этот конкретный сценарий, но заметил, что pesterfish импортирует именно simplejson, когда кажется, что он отлично справится со стандартной библиотекой json. Подробнее об этом см. stackoverflow.com/a/712799/722332.

zigg 02.05.2012 23:24

-1 Ваш код не работает. а) Он игнорирует атрибуты тегов: xml2json.xml2json('<a href = "111"> <b href = "222" /> </a>', no_options) отбрасывает атрибуты href и выдает только '{"a": {"b": null}}'

smci 19.08.2014 18:39

б) Как ни странно, требуется обязательный второй аргумент, который должен быть объектом Python и иметь атрибут pretty, даже если это False: options = type("anonobj", (object,), dict(pretty=False)). Вместо использования options = {} по умолчанию и использования options.getkey('pretty',default=False)

smci 19.08.2014 18:45

c) И он возвращает строку из json.dumps, а не фактический объект json. Вместо этого нам может понадобиться объект json. Вы можете добавить необязательный аргумент to_string=False.

smci 19.08.2014 18:47

xmltodict (полное раскрытие: это я написал) может помочь вам преобразовать ваш XML в структуру dict + list + string, следуя этому "стандарт". Он основан на Эмигрант, поэтому работает очень быстро и не требует загрузки всего XML-дерева в память.

Получив эту структуру данных, вы можете сериализовать ее в JSON:

import xmltodict, json

o = xmltodict.parse('<e> <a>text</a> <a>text</a> </e>')
json.dumps(o) # '{"e": {"a": ["text", "text"]}}'

Вы написали обратное? Думаю, мне было бы интересно такое животное.

zigg 02.05.2012 23:26

Нет, но это не так уж сложно сделать. Однако я не знаю, что делать с «полуструктурированным» xml. Такие вещи, как <a>text <b>c</b> moretext</a> -> {'a': {'#text': 'text moretext', 'b': 'c'}} -> что теперь?

Martin Blech 09.05.2012 04:19

Если строго следовать статье Гесснера, на самом деле у вас должен был быть {'a': 'text <b>c</b> moretext'}, который затем возвращается к <a>text &lt;b&gt;c&lt;/b&gt; moretext</a> ... несоответствие между JSON и XML делает подобные ситуации очень неудобными. Я все равно попытался использовать ElementTree для работы с API, которую я выполняю. github.com/zigg/xon

zigg 09.05.2012 05:03

@MartinBlech xmltodict отлично работает для моего проекта чтения RSS-каналов ebay, спасибо!

Haqa 17.09.2012 03:31

xmltodict, похоже, имеет "неразборчивый" метод, который теперь будет делать обратное

Rob Dennis 06.05.2014 21:22

есть проблема с библиотекой libexpat, она не может обрабатывать скобки полной ширины в имени элемента.

Wei Qiu 13.02.2018 13:00

Другие вопросы по теме