【问题标题】:How to convert XML to JSON in Python? [duplicate]如何在 Python 中将 XML 转换为 JSON? [复制]
【发布时间】:2010-10-03 02:02:12
【问题描述】:

可能重复:
Converting XML to JSON using Python?

我在 App Engine 上做一些工作,我需要将从远程服务器检索到的 XML 文档转换为等效的 JSON 对象。

我使用xml.dom.minidom 来解析urlfetch 返回的XML 数据。我还尝试使用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)

【问题讨论】:

标签: python xml json


【解决方案1】:

xmltodict(完全公开:我写的)可以帮助您将 XML 转换为 dict+list+string 结构,遵循此"standard"。它基于Expat,因此速度非常快,不需要在内存中加载整个 XML 树。

一旦你有了那个数据结构,你就可以将它序列化为 JSON:

import xmltodict, json

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

【讨论】:

  • 你写反了吗?我想我会对这样的动物感兴趣。
  • 我没有,但这听起来并不难。不过,我不知道如何处理“半结构化”xml。 &lt;a&gt;text &lt;b&gt;c&lt;/b&gt; moretext&lt;/a&gt; -> {'a': {'#text': 'text moretext', 'b': 'c'}} -> 现在怎么办?
  • 如果你严格按照 Goessner 的文章,你实际上应该有{'a': 'text &lt;b&gt;c&lt;/b&gt; moretext'},然后往返到&lt;a&gt;text &amp;lt;b&amp;gt;c&amp;lt;/b&amp;gt; moretext&lt;/a&gt;... JSON 和 XML 之间的不匹配使得这种情况非常尴尬。不过,对于我正在做的 API 工作,我还是使用ElementTree 对整个事情进行了尝试。 github.com/zigg/xon
  • @MartinBlech xmltodict 非常适合我的 ebay rss 阅读器项目,谢谢!
  • xmltodict 似乎有一个“unparse”方法,现在可以执行相反的操作
【解决方案2】:

Soviut 对 lxml objectify 的建议很好。使用特殊子类的 simplejson,您可以将 lxml 对象化结果转换为 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 实例的 encode 方法

请注意,Koen 的观点在这里非常有效,上面的解决方案仅适用于简单嵌套的 xml,并且不包括根元素的名称。这可以修复。

我已将这个类包含在一个要点中:http://gist.github.com/345559

【讨论】:

  • 如果我的标签有多个具有相同标签名称的子标签怎么办?
  • @vittore: 你可以用上面的return [i.__dict__ for i in o] 替换return o.__dict__ 来处理多个孩子。
  • @weaver 这几乎就是我所做的。
【解决方案3】:

我认为 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 这篇文章是关于往返 XML 和 JSON 的一般问题。这个话题非常贴切。不要让最后的 JavaScript 代码让你失望。
  • @Koen,看起来像这样。 { "persons": { "person": { "-name": "Koen Bok", "locations": { "-name": "defaults", "location": { "-long": "123", " -lat": "384" } } } } }
【解决方案4】:

Jacob Smullyan 编写了一个名为 pesterfish 的实用程序,它使用 effbot 的 ElementTree 将 XML 转换为 JSON。

【讨论】:

  • 用 pip 安装好像坏了:UnicodeDecodeError: 'utf8' codec can't decode byte 0x8b in position 1: invalid start byte
【解决方案5】:

一种可能性是使用 lxml module 中的 Objectify 或 ElementTree。 python xml.etree 模块中也提供了旧版本的 ElementTree。其中任何一个都会将您的 xml 转换为 Python 对象,然后您可以使用 simplejson 将对象序列化为 JSON。

虽然这似乎是一个痛苦的中间步骤,但当您同时处理 XML 普通 Python 对象时,它开始变得更有意义。

【讨论】:

    【解决方案6】:

    一般来说,您希望从 XML 转换为您的语言的常规对象(因为通常有合理的工具可以做到这一点,而且转换难度更大)。然后从 Plain Old Object 生成 JSON —— 也有用于此的工具,而且它是一个非常简单的序列化(因为 JSON 是“对象表示法”,自然适合序列化对象)。 我假设 Python 有一套工具。

    【讨论】:

      【解决方案7】:

      我基于 pesterfesh 编写了一个基于命令行的小型 Python 脚本,它正是这样做的:

      https://github.com/hay/xml2json

      【讨论】:

      • 此链接已损坏。如果更新它会很好(如果脚本仍然存在)。
      • 糟糕,我将脚本移到了它自己的存储库中。感谢您注意到 404!
      • 谢谢,这是完美的。需要注意的一点是它需要安装simplejson:sudo easy_install simplejson
      • @srs2012 我没有尝试过这个特定的脚本,但我注意到pesterfish 会导入simplejson,特别是当它看起来与标准库json 配合时会很好。有关更多信息,请参阅stackoverflow.com/a/712799/722332
      • -1 您的代码不起作用。 a) 它忽略标签的属性:xml2json.xml2json('&lt;a href="111"&gt; &lt;b href="222" /&gt; &lt;/a&gt;', no_options) 删除 href 属性,只给出 '{"a": {"b": null}}'
      猜你喜欢
      • 2010-10-03
      • 2017-05-18
      • 2013-12-04
      • 2012-02-17
      • 1970-01-01
      • 2019-03-27
      • 1970-01-01
      • 1970-01-01
      • 2015-01-13
      相关资源
      最近更新 更多