使用Python将XML转换为JSON?

Pet*_* II 154 python xml json converter

我已经在网上看到了很多笨拙的XML-> JSON代码,并且与Stack的用户进行了一些交互,我相信这些人群可以比谷歌搜索结果的前几页更有用.

因此,我们正在解析天气预报,我们需要在众多网站上填充天气小部件.我们现在正在研究基于Python的解决方案.

这个public weather.com RSS提要是我们要解析的一个很好的例子(我们的实际weather.com提要包含其他信息,因为它们与他们合作).

简而言之,我们应该如何使用Python将XML转换为JSON?

Mar*_*ech 265

xmltodict(全面披露:我写的)可以帮助你的XML转换为一个字典+列表+弦结构,下面这个"标准".它是基于Expat的,所以它非常快,不需要在内存中加载整个XML树.

拥有该数据结构后,可以将其序列化为JSON:

import xmltodict, json

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


Dan*_*ski 56

有XML和JSON之间没有"一对一"映射,所以将一个到另一个必然需要的,你想要什么一定的理解的结果.

话虽这么说,Python的标准库有几个用于解析XML的模块(包括DOM,SAX和ElementTree).从Python 2.6开始,json模块中包含了对与JSON进行Python数据结构转换的支持.

所以基础设施就在那里.

  • xmljson IMHO是开箱即用,支持各种约定的最快方法。https://pypi.org/project/xmljson/ (2认同)

S A*_*and 20

您可以使用xmljson库使用不同的XML JSON约定进行转换.

例如,这个XML:

<p id="1">text</p>
Run Code Online (Sandbox Code Playgroud)

通过BadgerFish约定翻译成:

{
  'p': {
    '@id': 1,
    '$': 'text'
  }
}
Run Code Online (Sandbox Code Playgroud)

并通过GData约定到此(不支持属性):

{
  'p': {
    '$t': 'text'
  }
}
Run Code Online (Sandbox Code Playgroud)

...并通过Parker约定(不支持属性):

{
  'p': 'text'
}
Run Code Online (Sandbox Code Playgroud)

可以使用相同的约定从XML转换为JSON,从JSON转换为XML:

>>> import json, xmljson
>>> from lxml.etree import fromstring, tostring
>>> xml = fromstring('<p id="1">text</p>')
>>> json.dumps(xmljson.badgerfish.data(xml))
'{"p": {"@id": 1, "$": "text"}}'
>>> xmljson.parker.etree({'ul': {'li': [1, 2]}})
# Creates [<ul><li>1</li><li>2</li></ul>]
Run Code Online (Sandbox Code Playgroud)

披露:我写了这个库.希望它能帮助未来的搜索者.

  • 这是一个非常酷的库,但请在阅读更多答案之前阅读[如何提供个人开源库?](https://meta.stackexchange.com/q/229085). (4认同)
  • 感谢 Anand 提供的解决方案 - 它似乎运行良好,没有外部依赖项,并且在如何使用不同约定处理属性方面提供了很大的灵活性。正是我所需要的,也是我找到的最灵活、最简单的解决方案。 (3认同)

jnh*_*tin 12

对于可能仍然需要这个的任何人。这是一个更新的、简单的代码来进行这种转换。

from xml.etree import ElementTree as ET

xml    = ET.parse('FILE_NAME.xml')
parsed = parseXmlToJson(xml)


def parseXmlToJson(xml):
  response = {}

  for child in list(xml):
    if len(list(child)) > 0:
      response[child.tag] = parseXmlToJson(child)
    else:
      response[child.tag] = child.text or ''

    # one-liner equivalent
    # response[child.tag] = parseXmlToJson(child) if len(list(child)) > 0 else child.text or ''

  return response
Run Code Online (Sandbox Code Playgroud)

  • 类型错误:“ElementTree”对象不可迭代 (3认同)

小智 8

如果有时候你只得到响应代码而不是所有数据,那么像json parse这样的错误会在那里,所以你需要将它转换为文本

import xmltodict

data = requests.get(url)
xpars = xmltodict.parse(data.text)
json = json.dumps(xpars)
print json 
Run Code Online (Sandbox Code Playgroud)


the*_*hai 7

有一种方法可以将基于XML的标记作为JSON传输,允许它无损地转换回原始形式.见http://jsonml.org/.

它是一种JSON的XSLT.我希望你觉得这对你有帮助


小智 7

这是我为此构建的代码.没有解析内容,只是简单的转换.

from xml.dom import minidom
import simplejson as json
def parse_element(element):
    dict_data = dict()
    if element.nodeType == element.TEXT_NODE:
        dict_data['data'] = element.data
    if element.nodeType not in [element.TEXT_NODE, element.DOCUMENT_NODE, 
                                element.DOCUMENT_TYPE_NODE]:
        for item in element.attributes.items():
            dict_data[item[0]] = item[1]
    if element.nodeType not in [element.TEXT_NODE, element.DOCUMENT_TYPE_NODE]:
        for child in element.childNodes:
            child_name, child_dict = parse_element(child)
            if child_name in dict_data:
                try:
                    dict_data[child_name].append(child_dict)
                except AttributeError:
                    dict_data[child_name] = [dict_data[child_name], child_dict]
            else:
                dict_data[child_name] = child_dict 
    return element.nodeName, dict_data

if __name__ == '__main__':
    dom = minidom.parse('data.xml')
    f = open('data.json', 'w')
    f.write(json.dumps(parse_element(dom), sort_keys=True, indent=4))
    f.close()
Run Code Online (Sandbox Code Playgroud)


Mic*_*son 6

我建议不要直接转换。将 XML 转换为对象,然后从对象转换为 JSON。

在我看来,这给出了 XML 和 JSON 如何对应的更清晰的定义。

正确使用需要时间,您甚至可以编写工具来帮助您生成其中的一些,但它大致如下所示:

class Channel:
  def __init__(self)
    self.items = []
    self.title = ""

  def from_xml( self, xml_node ):
    self.title = xml_node.xpath("title/text()")[0]
    for x in xml_node.xpath("item"):
      item = Item()
      item.from_xml( x )
      self.items.append( item )

  def to_json( self ):
    retval = {}
    retval['title'] = title
    retval['items'] = []
    for x in items:
      retval.append( x.to_json() )
    return retval

class Item:
  def __init__(self):
    ...

  def from_xml( self, xml_node ):
    ...

  def to_json( self ):
    ...
Run Code Online (Sandbox Code Playgroud)


小智 5

您可能需要查看http://designtheory.org/library/extrep/designdb-1.0.pdf.该项目从一个大型XML文件库的XML到JSON转换开始.在转换中进行了大量研究,并且生成了最简单直观的XML - > JSON映射(在文档的早期描述).总之,将所有内容转换为JSON对象,并将重复块作为对象列表.

对象意味着键/值对(Python中的字典,Java中的hashmap,JavaScript中的对象)

没有映射回XML以获取相同的文档,原因是,未知键/值对是属性还是属性<key>value</key>,因此该信息丢失.

如果你问我,属性是一个黑客入手; 然后他们再次为HTML做得很好.