将Solr XML解析为Python字典
我刚开始学习Python,想把一个XML文档(里面有一些Solr实例的文档)转换成Python字典。可是我在实现这个过程中遇到了困难。我尝试过使用ElementTree和minidom,但总是得不到想要的结果。
这是我的XML结构:
<add>
<doc>
<field name="genLatitude">45.639968</field>
<field name="carOfficeHoursEnd">2000-01-01T09:00:00.000Z</field>
<field name="genLongitude">5.879745</field>
</doc>
<doc>
<field name="genLatitude">46.639968</field>
<field name="carOfficeHoursEnd">2000-01-01T09:00:00.000Z</field>
<field name="genLongitude">6.879745</field>
</doc>
</add>
我想把它转换成一个看起来像这样的字典:
doc {
"genLatitude": '45.639968',
"carOfficeHoursEnd": '2000-01-01T09:00:00.000Z',
"genLongitude": '5.879745',
}
我对字典的工作原理不是很熟悉,不知道有没有办法把所有的“docs”放到一个字典里。
谢谢!
4 个回答
1
这里有一个可能的解决方案,使用了ElementTree,并且为了示例的清晰,输出格式进行了美化:
>>> import xml.etree.ElementTree as etree
>>> root = etree.parse(document).getroot()
>>> docs = []
>>> for doc in root.findall('doc'):
... fields = {}
... for field in doc:
... fields[field.attrib['name']] = field.text
... docs.append(fields)
...
>>> print docs
[{'genLongitude': '5.879745',
'genLatitude': '45.639968',
'carOfficeHoursEnd': '2000-01-01T09:00:00.000Z'},
{'genLongitude': '6.879745',
'genLatitude': '46.639968',
'carOfficeHoursEnd': '2000-01-01T09:00:00.000Z'}]
你展示的这个XML文档没有办法区分每一个doc
,所以我认为用列表来收集每个字典是最好的选择。
其实,如果你想把每个doc
的数据放进另一个字典里,当然可以,但你需要为这个字典选择一个合适的键。比如,可以使用Python为每个对象提供的id
,你可以这样写:
>>> docs = {}
>>> for doc in root.findall('doc'):
... fields = {}
... for field in doc:
... fields[field.attrib['name']] = field.text
... docs[id(fields)] = fields
...
>>> print docs
{3076930796L: {'genLongitude': '6.879745',
'genLatitude': '46.639968',
'carOfficeHoursEnd': '2000-01-01T09:00:00.000Z'},
3076905540L: {'genLongitude': '5.879745',
'genLatitude': '45.639968',
'carOfficeHoursEnd': '2000-01-01T09:00:00.000Z'}}
这个例子只是为了让你看到如何使用外部字典。如果你决定走这条路,我建议你找一个有意义且实用的键,而不是使用id
返回的对象内存地址,因为这个地址在每次运行时可能会变化。
2
如果你在请求参数中加上 wt=python
,Solr 就可以返回一个 Python 字典。要把这个文本响应转换成 Python 对象,可以使用 ast.literal_eval(text_response)
。
这样做比解析 XML 简单多了。
3
输出
import xml.etree.cElementTree as etree
from pprint import pprint
root = etree.fromstring(xmlstr) # or etree.parse(filename_or_file).getroot()
docs = [{f.attrib['name']: f.text for f in doc.iterfind('field[@name]')}
for doc in root.iterfind('doc')]
pprint(docs)
[{'carOfficeHoursEnd': '2000-01-01T09:00:00.000Z',
'genLatitude': '45.639968',
'genLongitude': '5.879745'},
{'carOfficeHoursEnd': '2000-01-01T09:00:00.000Z',
'genLatitude': '46.639968',
'genLongitude': '6.879745'}]
xmlstr = """
<add>
<doc>
<field name="genLatitude">45.639968</field>
<field name="carOfficeHoursEnd">2000-01-01T09:00:00.000Z</field>
<field name="genLongitude">5.879745</field>
</doc>
<doc>
<field name="genLatitude">46.639968</field>
<field name="carOfficeHoursEnd">2000-01-01T09:00:00.000Z</field>
<field name="genLongitude">6.879745</field>
</doc>
</add>
"""
这里的 xmlstr
是: