我在网上看到过相当多笨拙的XML->JSON代码,并与Stack的用户进行了一些互动,我相信这群人能比谷歌结果的前几页提供更多的帮助。
因此,我们正在解析一个天气提要,我们需要在许多网站上填充天气小部件。我们现在正在研究基于python的解决方案。
这个公共weather.com RSS提要是我们将要解析的内容的一个很好的例子(我们实际的weather.com提要包含额外的信息,因为与他们有合作关系)。
简而言之,如何使用Python将XML转换为JSON ?
我在网上看到过相当多笨拙的XML->JSON代码,并与Stack的用户进行了一些互动,我相信这群人能比谷歌结果的前几页提供更多的帮助。
因此,我们正在解析一个天气提要,我们需要在许多网站上填充天气小部件。我们现在正在研究基于python的解决方案。
这个公共weather.com RSS提要是我们将要解析的内容的一个很好的例子(我们实际的weather.com提要包含额外的信息,因为与他们有合作关系)。
简而言之,如何使用Python将XML转换为JSON ?
当前回答
这里的东西是主动维护的,到目前为止是我最喜欢的:python中的xml2json
其他回答
可能最简单的方法是将XML解析为字典,然后用simplejson序列化它。
XML和JSON之间不存在“一对一”的映射,因此将一个转换为另一个必须了解您想对结果做什么。
也就是说,Python的标准库有几个用于解析XML的模块(包括DOM、SAX和ElementTree)。从Python 2.6开始,JSON模块中包含了对Python数据结构与JSON之间转换的支持。
所以基础设施就在那里。
有一种方法可以将基于xml的标记传输为JSON,允许它无损地转换回原始形式。见http://jsonml.org/。
它是一种JSON的XSLT。我希望这对你有帮助
当我在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>
我建议不要直接转换。将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 ):
...