使用 Python 将 XML 转换为 JSON?

Converting XML to JSON using Python?

提问人:Pete Karl II 提问时间:10/10/2008 最后编辑:dreftymacPete Karl II 更新时间:5/2/2023 访问量:380704

问:

我在网络上看到了相当多的笨拙的 XML->JSON 代码,并且与 Stack 的用户进行了一段时间的互动,我相信这群人可以比 Google 结果的前几页提供更多帮助。

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

这个公共 weather.com RSS 提要是我们将要解析的内容的一个很好的例子(由于与他们建立了合作伙伴关系,我们的实际 weather.com 提要包含其他信息)。

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

python json xml 转换器

评论

0赞 Andreas Haferburg 10/21/2021
另请参阅 stackoverflow.com/questions/418497/...

答:

4赞 dguaraglia 10/10/2008 #1

好吧,可能最简单的方法就是将 XML 解析为字典,然后使用 simplejson 对其进行序列化。

70赞 Dan Lenski 10/10/2008 #2

XML 和 JSON 之间没有“一对一”映射,因此将一个映射转换为另一个映射必然需要了解要对结果执行的操作

话虽如此,Python 的标准库有几个用于解析 XML 的模块(包括 DOM、SAX 和 ElementTree)。从 Python 2.6 开始,json 模块中包含对将 Python 数据结构与 JSON 相互转换的支持。

所以基础设施就在那里。

评论

4赞 nitinr708 12/5/2018
xmljson 恕我直言,它是使用最快的,支持开箱即用的各种约定。pypi.org/project/xmljson
0赞 Dan Lenski 12/5/2018
在较新的答案中已经提到过。它仍然只涵盖了有效 XML 构造的一小部分,但可能是人们在实践中使用的大部分内容。
2赞 Luka Marinko 10/11/2008 #3

虽然用于 XML 解析的内置库非常好,但我偏爱 lxml

但是对于解析 RSS 提要,我推荐 Universal Feed Parser,它也可以解析 Atom。 它的主要优点是它甚至可以消化大多数畸形饲料。

Python 2.6 已经包含一个 JSON 解析器,但速度更快的更新版本以 simplejson 的形式提供。

有了这些工具,构建你的应用程序应该不会那么困难。

5赞 pykler 10/8/2010 #4

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

表示键/值对的对象(Python 中的字典,Java 中的 hashmap,JavaScript 中的对象)

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

如果你问我,属性是一个开始的技巧;然后,它们再次适用于HTML。

7赞 themihai 6/10/2011 #5

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

它是 JSON 的一种 XSLT。我希望它对你有所帮助

2赞 Andrew_1510 4/4/2012 #6

我发现对于简单的XML截图,使用正则表达式可以省去麻烦。例如:

# <user><name>Happy Man</name>...</user>
import re
names = re.findall(r'<name>(\w+)<\/name>', xml_string)
# do some thing to names

正如@Dan所说,要通过XML解析来做到这一点,没有一劳永逸的解决方案,因为数据是不同的。我的建议是使用 lxml。虽然还没有完成 json,但 lxml.objectify 给出了安静的好结果:

>>> from lxml import objectify
>>> root = objectify.fromstring("""
... <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...   <a attr1="foo" attr2="bar">1</a>
...   <a>1.2</a>
...   <b>1</b>
...   <b>true</b>
...   <c>what?</c>
...   <d xsi:nil="true"/>
... </root>
... """)

>>> print(str(root))
root = None [ObjectifiedElement]
    a = 1 [IntElement]
      * attr1 = 'foo'
      * attr2 = 'bar'
    a = 1.2 [FloatElement]
    b = 1 [IntElement]
    b = True [BoolElement]
    c = 'what?' [StringElement]
    d = None [NoneElement]
      * xsi:nil = 'true'

评论

1赞 Pooya 7/4/2012
但它删除了重复的节点
373赞 Martin Blech 4/18/2012 #7

xmltodict(完全披露:我写的)可以帮助你按照这个“标准”将XML转换为dict+list+string结构。它是基于Expat的,因此速度非常快,不需要在内存中加载整个XML树。

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

import xmltodict, json

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

评论

0赞 sayth 5/14/2014
@Martin Blech 如果我从我的 django 模型文件创建一个 json 文件。如何映射我的 xml 文件以将必填字段的 xml 转换为 json?
1赞 Martin Blech 5/15/2014
@sayth我认为您应该将其作为单独的 SO 问题发布。
0赞 sayth 5/16/2014
@Martin 布莱奇。我添加了一个问题,但很难适应,我是初学者,所以提供了尽可能多的信息,但我希望您可能需要更清晰的信息 stackoverflow.com/q/23676973/461887
0赞 sancelot 1/31/2019
经过这么长时间,我有点惊讶 xmltodict 在某些 linux 发行版中不是“标准”库。尽管似乎直接从我们可以阅读的内容中完成这项工作,但不幸的是,我将使用另一种解决方案,例如 xslt 转换
1赞 Trect 11/20/2019
非常感谢您编写了这个出色的库。虽然可以完成xml到dict的工作,但使用该库非常容易bs4
7赞 Michael Anderson 4/18/2012 #8

我建议不要进行直接转换。将 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 ):
    ...

评论

0赞 Quuxplusone 12/9/2021
如果没有关于变量来自哪里的提示(它是什么类型?它的方法有什么作用?),这个答案不是很有用。xml_node.xpath
9赞 Paulo Vj 4/19/2012 #9

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

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()
37赞 S Anand 9/20/2015 #10

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

例如,以下 XML:

<p id="1">text</p>

通过 BadgerFish 约定翻译为:

{
  'p': {
    '@id': 1,
    '$': 'text'
  }
}

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

{
  'p': {
    '$t': 'text'
  }
}

...并通过 Parker 约定进入这个(不支持属性):

{
  'p': 'text'
}

可以使用相同的方法从 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>]

披露:我写了这个库。希望它对未来的搜索者有所帮助。

评论

6赞 Martijn Pieters 9/20/2015
这是一个非常酷的库,但在你发布更多答案之前,请先阅读如何提供个人开源库?
1赞 S Anand 9/21/2015
谢谢@MartijnPieters - 我刚刚经历了这个,并将确保我坚持下去。
3赞 mbbeme 10/4/2016
感谢 Anand 提供的解决方案 - 它似乎运行良好,没有外部依赖关系,并且在如何使用不同的约定处理属性方面提供了很大的灵活性。这正是我所需要的,也是我找到的最灵活、最简单的解决方案。
0赞 Patrik Beck 4/6/2017
谢谢 Anand - 不幸的是,我无法让它使用 utf8 编码解析 XML。通过源代码,似乎忽略了通过 XMLParser(..) 设置的编码
1赞 S Anand 5/10/2017
@PatrikBeck您能分享一个带有 utf8 编码的 XML 的小例子吗?
2赞 shx2 10/20/2016 #11

我的答案解决了特定(并且有些常见)的情况,即您实际上不需要将整个 xml 转换为 json,但您需要的是遍历/访问 xml 的特定部分,并且您需要它快速简单(使用类似 json/dict 的操作)。

方法

为此,需要注意的是,使用 xml 解析 etree 是超快的。在大多数其他答案中,缓慢的部分是第二遍:遍历 etree 结构(通常在 python-land 中),将其转换为 json。lxml

这让我想到了我找到最适合这种情况的方法:使用 解析 xml,然后(懒惰地)包装 etree 节点,为它们提供类似 dict 的接口。lxml

法典

代码如下:

from collections import Mapping
import lxml.etree

class ETreeDictWrapper(Mapping):

    def __init__(self, elem, attr_prefix = '@', list_tags = ()):
        self.elem = elem
        self.attr_prefix = attr_prefix
        self.list_tags = list_tags

    def _wrap(self, e):
        if isinstance(e, basestring):
            return e
        if len(e) == 0 and len(e.attrib) == 0:
            return e.text
        return type(self)(
            e,
            attr_prefix = self.attr_prefix,
            list_tags = self.list_tags,
        )

    def __getitem__(self, key):
        if key.startswith(self.attr_prefix):
            return self.elem.attrib[key[len(self.attr_prefix):]]
        else:
            subelems = [ e for e in self.elem.iterchildren() if e.tag == key ]
            if len(subelems) > 1 or key in self.list_tags:
                return [ self._wrap(x) for x in subelems ]
            elif len(subelems) == 1:
                return self._wrap(subelems[0])
            else:
                raise KeyError(key)

    def __iter__(self):
        return iter(set( k.tag for k in self.elem) |
                    set( self.attr_prefix + k for k in self.elem.attrib ))

    def __len__(self):
        return len(self.elem) + len(self.elem.attrib)

    # defining __contains__ is not necessary, but improves speed
    def __contains__(self, key):
        if key.startswith(self.attr_prefix):
            return key[len(self.attr_prefix):] in self.elem.attrib
        else:
            return any( e.tag == key for e in self.elem.iterchildren() )


def xml_to_dictlike(xmlstr, attr_prefix = '@', list_tags = ()):
    t = lxml.etree.fromstring(xmlstr)
    return ETreeDictWrapper(
        t,
        attr_prefix = '@',
        list_tags = set(list_tags),
    )

这种实现并不完整,例如,它不能完全支持元素同时具有文本和属性,或者同时具有文本和子元素的情况(只是因为我在编写它时不需要它......不过,改进它应该很容易。

速度

在我的特定用例中,我只需要处理 xml 的特定元素,与使用 @Martin Blech 的 xmltodict 然后直接遍历 dict 相比,这种方法的速度提高了 70 倍 (!)

奖金

作为奖励,由于我们的结构已经是类似字典的,因此我们免费获得了另一种替代实现。我们只需要将类似字典的结构传递给 。像这样:xml2jsonjson.dumps

def xml_to_json(xmlstr, **kwargs):
    x = xml_to_dictlike(xmlstr, **kwargs)
    return json.dumps(x)

如果您的 xml 包含属性,则需要使用一些字母数字(例如“ATTR_”),以确保键是有效的 json 键。attr_prefix

我还没有对这部分进行基准测试。

评论

2赞 Vlad T. 7/11/2019
如果我尝试这样做,它会说“ETreeDictWrapper”类型的对象不可 JSON 序列化json.dumps(tree)
0赞 daparic 2/10/2017 #12

这里的东西是积极维护的,到目前为止是我的最爱:python中的xml2json

评论

1赞 Coin Graham 5/6/2021
这已弃用。
0赞 daparic 5/6/2021
事实上。我们能知道 github 存储库移动到只读/存档的确切日期吗?我看到的只是最后一次提交是 2019 年。谢谢。
1赞 Coin Graham 5/6/2021
“此模块已弃用,将不再更新(2019 年 5 月)”
4赞 shrewmouse 5/10/2017 #13

当我在 python 中使用 XML 做任何事情时,我几乎总是使用 lxml 包。我怀疑大多数人都使用 lxml。您可以使用 xmltodict,但您必须支付再次解析 XML 的代价。

要使用 lxml 将 XML 转换为 json,您需要:

  1. 使用 lxml 解析 XML 文档
  2. 将 lxml 转换为字典
  3. 转换list到json

我在我的项目中使用以下类。使用 toJson 方法。

from lxml import etree 
import json


class Element:
    '''
    Wrapper on the etree.Element class.  Extends functionality to output element
    as a dictionary.
    '''

    def __init__(self, element):
        '''
        :param: element a normal etree.Element instance
        '''
        self.element = element

    def toDict(self):
        '''
        Returns the element as a dictionary.  This includes all child elements.
        '''
        rval = {
            self.element.tag: {
                'attributes': dict(self.element.items()),
            },
        }
        for child in self.element:
            rval[self.element.tag].update(Element(child).toDict())
        return rval


class XmlDocument:
    '''
    Wraps lxml to provide:
        - cleaner access to some common lxml.etree functions
        - converter from XML to dict
        - converter from XML to json
    '''
    def __init__(self, xml = '<empty/>', filename=None):
        '''
        There are two ways to initialize the XmlDocument contents:
            - String
            - File

        You don't have to initialize the XmlDocument during instantiation
        though.  You can do it later with the 'set' method.  If you choose to
        initialize later XmlDocument will be initialized with "<empty/>".

        :param: xml Set this argument if you want to parse from a string.
        :param: filename Set this argument if you want to parse from a file.
        '''
        self.set(xml, filename) 

    def set(self, xml=None, filename=None):
        '''
        Use this to set or reset the contents of the XmlDocument.

        :param: xml Set this argument if you want to parse from a string.
        :param: filename Set this argument if you want to parse from a file.
        '''
        if filename is not None:
            self.tree = etree.parse(filename)
            self.root = self.tree.getroot()
        else:
            self.root = etree.fromstring(xml)
            self.tree = etree.ElementTree(self.root)


    def dump(self):
        etree.dump(self.root)

    def getXml(self):
        '''
        return document as a string
        '''
        return etree.tostring(self.root)

    def xpath(self, xpath):
        '''
        Return elements that match the given xpath.

        :param: xpath
        '''
        return self.tree.xpath(xpath);

    def nodes(self):
        '''
        Return all elements
        '''
        return self.root.iter('*')

    def toDict(self):
        '''
        Convert to a python dictionary
        '''
        return Element(self.root).toDict()

    def toJson(self, indent=None):
        '''
        Convert to JSON
        '''
        return json.dumps(self.toDict(), indent=indent)


if __name__ == "__main__":
    xml='''<system>
    <product>
        <demod>
            <frequency value='2.215' units='MHz'>
                <blah value='1'/>
            </frequency>
        </demod>
    </product>
</system>
'''
    doc = XmlDocument(xml)
    print doc.toJson(indent=4)

内置 main 的输出为:

{
    "system": {
        "attributes": {}, 
        "product": {
            "attributes": {}, 
            "demod": {
                "attributes": {}, 
                "frequency": {
                    "attributes": {
                        "units": "MHz", 
                        "value": "2.215"
                    }, 
                    "blah": {
                        "attributes": {
                            "value": "1"
                        }
                    }
                }
            }
        }
    }
}

这是此 xml 的转换:

<system>
    <product>
        <demod>
            <frequency value='2.215' units='MHz'>
                <blah value='1'/>
            </frequency>
        </demod>
    </product>
</system>

评论

1赞 Chris Collett 6/26/2021
这是否处理标签中的文本(例如)?<text>Some text</text>
1赞 shrewmouse 6/26/2021
已经有一段时间了。不,但很容易做到。搭'text: self.element.texttoDict
17赞 jnhustin 11/3/2017 #14

给任何可能仍然需要这个的人。下面是一个更新的简单代码来执行此转换。

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

评论

1赞 hrbdg 8/10/2019
它至少在 Python 3.7 中起作用,但不幸的是,如果某些值在您的 xml 中,它会向键名称添加一些意外数据,例如根级节点上的 xmlns 标记显示在每个节点键中,如下所示: {'{maven.apache.org/POM/4.0.0}artifactId': 'test-service',它来自 xml,如下所示: <project xmlns=“maven.apache.org/POM/4.0.0” xsi:schemaLocation=“maven.apache.org/POM/4.0.0 maven.apache.org/xsd/maven-4.0.0.xsd” xmlns:xsi=“w3.org/2001/XMLSchema-instance”> <modelVersion>4.0.0</modelVersion>
7赞 gman 11/7/2020
TypeError:“ElementTree”对象不可迭代
1赞 Diego Magalhães 4/30/2021
从 list(xml) 更改为 xml.iter() 以避免 TypeError:“ElementTree”对象不可迭代
17赞 Akshay Kumbhar 5/12/2018 #15

如果有时您只得到响应代码而不是所有数据,那么就会出现像 json parse 这样的错误,因此您需要将其转换为文本

import xmltodict

data = requests.get(url)
xpars = xmltodict.parse(data.text)
json = json.dumps(xpars)
print json 

评论

0赞 elbe 1/31/2023
使用很好。请注意,不应设置哪个覆盖 json 包名称。xmltodictjson = json.dumps(xpars)
2赞 Robert Parelius 9/12/2018 #16

查看 lxml2json(披露:我写的)

https://github.com/rparelius/lxml2json

它非常快速、轻量级(只需要 LXML),一个优点是您可以控制某些元素是否转换为列表或字典

1赞 srth12 11/30/2018 #17

您可以使用 declxml。它具有多属性和复杂的嵌套支持等高级功能。你只需要为它编写一个简单的处理器。同样使用相同的代码,您也可以转换回 JSON。它相当简单,文档也很棒。

友情链接: https://declxml.readthedocs.io/en/latest/index.html

1赞 Liju 8/24/2020 #18

如果您不想使用任何外部库和第三方工具,请尝试以下代码。

法典

import re
import json

def getdict(content):
    res=re.findall("<(?P<var>\S*)(?P<attr>[^/>]*)(?:(?:>(?P<val>.*?)</(?P=var)>)|(?:/>))",content)
    if len(res)>=1:
        attreg="(?P<avr>\S+?)(?:(?:=(?P<quote>['\"])(?P<avl>.*?)(?P=quote))|(?:=(?P<avl1>.*?)(?:\s|$))|(?P<avl2>[\s]+)|$)"
        if len(res)>1:
            return [{i[0]:[{"@attributes":[{j[0]:(j[2] or j[3] or j[4])} for j in re.findall(attreg,i[1].strip())]},{"$values":getdict(i[2])}]} for i in res]
        else:
            return {res[0]:[{"@attributes":[{j[0]:(j[2] or j[3] or j[4])} for j in re.findall(attreg,res[1].strip())]},{"$values":getdict(res[2])}]}
    else:
        return content

with open("test.xml","r") as f:
    print(json.dumps(getdict(f.read().replace('\n',''))))

示例输入

<details class="4b" count=1 boy>
    <name type="firstname">John</name>
    <age>13</age>
    <hobby>Coin collection</hobby>
    <hobby>Stamp collection</hobby>
    <address>
        <country>USA</country>
        <state>CA</state>
    </address>
</details>
<details empty="True"/>
<details/>
<details class="4a" count=2 girl>
    <name type="firstname">Samantha</name>
    <age>13</age>
    <hobby>Fishing</hobby>
    <hobby>Chess</hobby>
    <address current="no">
        <country>Australia</country>
        <state>NSW</state>
    </address>
</details>

输出

[
  {
    "details": [
      {
        "@attributes": [
          {
            "class": "4b"
          },
          {
            "count": "1"
          },
          {
            "boy": ""
          }
        ]
      },
      {
        "$values": [
          {
            "name": [
              {
                "@attributes": [
                  {
                    "type": "firstname"
                  }
                ]
              },
              {
                "$values": "John"
              }
            ]
          },
          {
            "age": [
              {
                "@attributes": []
              },
              {
                "$values": "13"
              }
            ]
          },
          {
            "hobby": [
              {
                "@attributes": []
              },
              {
                "$values": "Coin collection"
              }
            ]
          },
          {
            "hobby": [
              {
                "@attributes": []
              },
              {
                "$values": "Stamp collection"
              }
            ]
          },
          {
            "address": [
              {
                "@attributes": []
              },
              {
                "$values": [
                  {
                    "country": [
                      {
                        "@attributes": []
                      },
                      {
                        "$values": "USA"
                      }
                    ]
                  },
                  {
                    "state": [
                      {
                        "@attributes": []
                      },
                      {
                        "$values": "CA"
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  },
  {
    "details": [
      {
        "@attributes": [
          {
            "empty": "True"
          }
        ]
      },
      {
        "$values": ""
      }
    ]
  },
  {
    "details": [
      {
        "@attributes": []
      },
      {
        "$values": ""
      }
    ]
  },
  {
    "details": [
      {
        "@attributes": [
          {
            "class": "4a"
          },
          {
            "count": "2"
          },
          {
            "girl": ""
          }
        ]
      },
      {
        "$values": [
          {
            "name": [
              {
                "@attributes": [
                  {
                    "type": "firstname"
                  }
                ]
              },
              {
                "$values": "Samantha"
              }
            ]
          },
          {
            "age": [
              {
                "@attributes": []
              },
              {
                "$values": "13"
              }
            ]
          },
          {
            "hobby": [
              {
                "@attributes": []
              },
              {
                "$values": "Fishing"
              }
            ]
          },
          {
            "hobby": [
              {
                "@attributes": []
              },
              {
                "$values": "Chess"
              }
            ]
          },
          {
            "address": [
              {
                "@attributes": [
                  {
                    "current": "no"
                  }
                ]
              },
              {
                "$values": [
                  {
                    "country": [
                      {
                        "@attributes": []
                      },
                      {
                        "$values": "Australia"
                      }
                    ]
                  },
                  {
                    "state": [
                      {
                        "@attributes": []
                      },
                      {
                        "$values": "NSW"
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
]
0赞 David Lee 2/24/2021 #19

不久前我在github上发布了一个..

https://github.com/davlee1972/xml_to_json

此转换器是用 Python 编写的,会将一个或多个 XML 文件转换为 JSON / JSONL 文件

它需要一个 XSD 架构文件来找出嵌套的 json 结构(字典与列表)和 json 等效数据类型。

python xml_to_json.py -x PurchaseOrder.xsd PurchaseOrder.xml

INFO - 2018-03-20 11:10:24 - Parsing XML Files..
INFO - 2018-03-20 11:10:24 - Processing 1 files
INFO - 2018-03-20 11:10:24 - Parsing files in the following order:
INFO - 2018-03-20 11:10:24 - ['PurchaseOrder.xml']
DEBUG - 2018-03-20 11:10:24 - Generating schema from PurchaseOrder.xsd
DEBUG - 2018-03-20 11:10:24 - Parsing PurchaseOrder.xml
DEBUG - 2018-03-20 11:10:24 - Writing to file PurchaseOrder.json
DEBUG - 2018-03-20 11:10:24 - Completed PurchaseOrder.xml

我还有一个后续的 xml 到 parquet 转换器,它以类似的方式工作

https://github.com/blackrock/xml_to_parquet