我在网上看到过相当多笨拙的XML->JSON代码,并与Stack的用户进行了一些互动,我相信这群人能比谷歌结果的前几页提供更多的帮助。
因此,我们正在解析一个天气提要,我们需要在许多网站上填充天气小部件。我们现在正在研究基于python的解决方案。
这个公共weather.com RSS提要是我们将要解析的内容的一个很好的例子(我们实际的weather.com提要包含额外的信息,因为与他们有合作关系)。
简而言之,如何使用Python将XML转换为JSON ?
我在网上看到过相当多笨拙的XML->JSON代码,并与Stack的用户进行了一些互动,我相信这群人能比谷歌结果的前几页提供更多的帮助。
因此,我们正在解析一个天气提要,我们需要在许多网站上填充天气小部件。我们现在正在研究基于python的解决方案。
这个公共weather.com RSS提要是我们将要解析的内容的一个很好的例子(我们实际的weather.com提要包含额外的信息,因为与他们有合作关系)。
简而言之,如何使用Python将XML转换为JSON ?
当前回答
我发现对于简单的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。物化的效果很好:
>>> 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'
其他回答
如果有些时候你只得到响应代码而不是所有的数据,那么像json解析这样的错误将会存在,所以你需要将它转换为文本
import xmltodict
data = requests.get(url)
xpars = xmltodict.parse(data.text)
json = json.dumps(xpars)
print json
虽然用于XML解析的内置库非常好,但我更倾向于lxml。
但是对于解析RSS提要,我推荐Universal Feed Parser,它也可以解析Atom。 它的主要优点是它甚至可以消化大多数畸形的饲料。
Python 2.6已经包含了一个JSON解析器,但是速度有所提高的新版本是simplejson。
有了这些工具,构建你的应用应该不会那么困难。
您可以使用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>]
披露:这个库是我写的。希望它能帮助未来的搜索者。
我发现对于简单的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。物化的效果很好:
>>> 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'
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"]}}'