【问题标题】:Convert XML to nested JSON object in specific format将 XML 转换为特定格式的嵌套 JSON 对象
【发布时间】:2019-05-28 04:33:03
【问题描述】:

这是我之前询问的关于从 XML 节点导出完全扁平结构的问题的后续:Converting an xml doc into a specific dot-expanded json structure

假设我有相同的 XML 开头:

<Item ID="288917">
  <Main>
    <Platform>iTunes</Platform>
    <PlatformID>353736518</PlatformID>
  </Main>
  <Genres>
    <Genre FacebookID="6003161475030">Comedy</Genre>
    <Genre FacebookID="6003172932634">TV-Show</Genre>
  </Genres>
  <Products>
    <Product Country="CA">
      <URL>https://itunes.apple.com/ca/tv-season/id353187108?i=353736518</URL>
      <Offers>
        <Offer Type="HDBUY">
          <Price>3.49</Price>
          <Currency>CAD</Currency>
        </Offer>
        <Offer Type="SDBUY">
          <Price>2.49</Price>
          <Currency>CAD</Currency>
        </Offer>
      </Offers>
    </Product>
    <Product Country="FR">
      <URL>https://itunes.apple.com/fr/tv-season/id353187108?i=353736518</URL>
      <Rating>Tout public</Rating>
      <Offers>
        <Offer Type="HDBUY">
          <Price>2.49</Price>
          <Currency>EUR</Currency>
        </Offer>
        <Offer Type="SDBUY">
          <Price>1.99</Price>
          <Currency>EUR</Currency>
        </Offer>
      </Offers>
    </Product>
  </Products>
</Item>

现在我想将其转换为特定格式的嵌套 json 对象(与 xmltodict 库略有不同。这是我想派生的结构:

{
    "Item[@ID]": 288917,
    "Item.Main.Platform": "iTunes",
    "Item.Main.PlatformID": "353736518",
    "Item.Genres": [
        {
            "[@FacebookID]": "6003161475030",
            "Value": "Comedy"
        },
        {
            "[@FacebookID]": "6003161475030",
            "Value": "TV-Show"
        }
    ],
    "Item.Products": [
        {
            "[@Country]": "CA",
            "URL": "https://itunes.apple.com/ca/tv-season/id353187108?i=353736518",
            "Offers.Offer": [
                {
                    "[@Type]": "HDBUY",
                    "Price": "3.49",
                    "Currency": "CAD"
                }
                {
                    "[@Type]": "SDBUY",
                    "Price": "2.49",
                    "Currency": "CAD"
                }
            ]
        },
        {
            "[@Country]": "FR",
            "URL": "https://itunes.apple.com/fr/tv-season/id353187108?i=353736518",
            "Offers.Offer": [
                {
                    "[@Type]": "HDBUY",
                    "Price": "3.49",
                    "Currency": "EUR"
                }
                {
                    "[@Type]": "SDBUY",
                    "Price": "1.99",
                    "Currency": "EUR"
                }
            ]
        }
    ]
}

主要区别不是将所有内容折叠成一个平面值列表,而是允许字典列表。这怎么可能?

【问题讨论】:

  • 您可以使用 XSLT 做到这一点,甚至是 1.0 版。

标签: python json xml recursion


【解决方案1】:

虽然执行上述操作可能是一个不错的挑战,但xmltodic 在这方面已经做得很好,只需稍作改动即可完成工作。

以下是对xmltodict 进行的更改:

  1. 将 var cdata_key#text 更改为 Value
  2. 将 var attr_prefix@ 更改为 [@
  3. 在 init 方法中添加新的 var attr_suffix=']'
  4. attr_key 更改为key = self.attr_prefix+self._build_name(key)+self.attr_suffix

这应该会给出您正在寻找的经过测试的模块的确切结果:

>>> from lxml import etree
>>> import xmltodict
>>> import json
>>> from utils import xmltodict
>>> node= etree.fromstring(s)
>>> d=xmltodict.parse(etree.tostring(node))
>>> print(json.dumps(d, indent=4))
{
    "Item": {
        "[@ID]": "288917",
        "Main": {
            "Platform": "iTunes",
            "PlatformID": "353736518"
        },
        "Genres": {
            "Genre": [
                {
                    "[@FacebookID]": "6003161475030",
                    "Value": "Comedy"
                },
                {
                    "[@FacebookID]": "6003172932634",
                    "Value": "TV-Show"
                }
            ]
        },
        "Products": {
            "Product": [
                {
                    "[@Country]": "CA",
                    "URL": "https://itunes.apple.com/ca/tv-season/id353187108?i=353736518",
                    "Offers": {
                        "Offer": [
                            {
                                "[@Type]": "HDBUY",
                                "Price": "3.49",
                                "Currency": "CAD"
                            },
                            {
                                "[@Type]": "SDBUY",
                                "Price": "2.49",
                                "Currency": "CAD"
                            }
                        ]
                    }
                },
                {
                    "[@Country]": "FR",
                    "URL": "https://itunes.apple.com/fr/tv-season/id353187108?i=353736518",
                    "Rating": "Tout public",
                    "Offers": {
                        "Offer": [
                            {
                                "[@Type]": "HDBUY",
                                "Price": "2.49",
                                "Currency": "EUR"
                            },
                            {
                                "[@Type]": "SDBUY",
                                "Price": "1.99",
                                "Currency": "EUR"
                            }
                        ]
                    }
                }
            ]
        }
    }
}

【讨论】:

  • 我认为这是最简单的方法。
猜你喜欢
  • 2021-10-29
  • 2023-03-08
  • 2019-12-26
  • 2019-02-01
  • 1970-01-01
  • 2022-08-16
  • 2021-02-04
  • 1970-01-01
相关资源
最近更新 更多