python - 将 XML 转换为特定格式的嵌套 JSON 对象
问题描述
这是我之前询问的关于从 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"
}
]
}
]
}
主要区别是不是将所有内容折叠成一个平面值列表,而是允许字典列表。怎么可能做到这一点?
解决方案
虽然执行上述操作可能是一个不错的挑战,xmltodic
但在这方面已经做得很好,并且可以通过轻微的改变来完成这项工作。
以下是要进行的更改xmltodict
:
- 将var cdata_key从更改
#text
为Value
。 - 将var attr_prefix从更改
@
为[@
。 - 将新 var 添加
attr_suffix=']'
到 init 方法。 - 将 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"
}
]
}
}
]
}
}
}
推荐阅读
- pyspark - 如何在 PySpark 中生成唯一的值对
- python - pathlib - 基本文件名。多个扩展
- javascript - 即使可以在 Mounted() 中登录,Vue JS 值也不会更新
- unix - Cron 作业指示错误 - mv: 无法访问
但文件已移动 - typescript - TS1011:元素访问表达式应该带一个参数
- angular - 错误:ExpressionChangedAfterItHasBeenCheckedError 变量 Angular?
- postgresql - 通过与 postgresql 中的其他列分组,将多个 JSONArray 行合并为一行
- docker - 如何通过Dockerfile中的脚本动态设置环境变量?
- php - Guzzle 中 curl_multi_exec 的等价物是什么?
- c++ - 将数组索引从一个类传递到另一个 C++