我在网上看到过相当多笨拙的XML->JSON代码,并与Stack的用户进行了一些互动,我相信这群人能比谷歌结果的前几页提供更多的帮助。
因此,我们正在解析一个天气提要,我们需要在许多网站上填充天气小部件。我们现在正在研究基于python的解决方案。
这个公共weather.com RSS提要是我们将要解析的内容的一个很好的例子(我们实际的weather.com提要包含额外的信息,因为与他们有合作关系)。
简而言之,如何使用Python将XML转换为JSON ?
我在网上看到过相当多笨拙的XML->JSON代码,并与Stack的用户进行了一些互动,我相信这群人能比谷歌结果的前几页提供更多的帮助。
因此,我们正在解析一个天气提要,我们需要在许多网站上填充天气小部件。我们现在正在研究基于python的解决方案。
这个公共weather.com RSS提要是我们将要解析的内容的一个很好的例子(我们实际的weather.com提要包含额外的信息,因为与他们有合作关系)。
简而言之,如何使用Python将XML转换为JSON ?
当前回答
我不久前在github上发表了一篇文章。
https://github.com/davlee1972/xml_to_json
这个转换器是用Python编写的,将一个或多个XML文件转换为JSON / JSONL文件
它需要一个XSD模式文件来找出嵌套的json结构(字典vs列表)和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到拼花转换器,以类似的方式工作
https://github.com/blackrock/xml_to_parquet
其他回答
如果有些时候你只得到响应代码而不是所有的数据,那么像json解析这样的错误将会存在,所以你需要将它转换为文本
import xmltodict
data = requests.get(url)
xpars = xmltodict.parse(data.text)
json = json.dumps(xpars)
print json
当我在python中处理XML时,我几乎总是使用lxml包。我怀疑大多数人都使用lxml。您可以使用xmltodict,但您将不得不再次解析XML。
用lxml将XML转换为json:
用lxml解析XML文档 将lxml转换为dict 将列表转换为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>
可以使用declxml。它具有高级特性,如多属性和复杂的嵌套支持。您只需要为它编写一个简单的处理器。同样,使用相同的代码,您也可以转换回JSON。它相当简单,文档也很棒。
链接:https://declxml.readthedocs.io/en/latest/index.html
XML和JSON之间不存在“一对一”的映射,因此将一个转换为另一个必须了解您想对结果做什么。
也就是说,Python的标准库有几个用于解析XML的模块(包括DOM、SAX和ElementTree)。从Python 2.6开始,JSON模块中包含了对Python数据结构与JSON之间转换的支持。
所以基础设施就在那里。
可能最简单的方法是将XML解析为字典,然后用simplejson序列化它。