我有一个xml
格式的文件:
<NewDataSet>
<Root>
<Phonemic>and</Phonemic>
<Phonetic>nd</Phonetic>
<Description/>
<Start>0</Start>
<End>8262</End>
</Root>
<Root>
<Phonemic>comfortable</Phonemic>
<Phonetic>comfetebl</Phonetic>
<Description>adj</Description>
<Start>61404</Start>
<End>72624</End>
</Root>
</NewDataSet>
我需要处理它,例如,当用户输入nd
时,程序会将其与<Phonetic>
标记匹配,并从and
返回<Phonemic>
部分。我想也许如果我可以将xml文件转换为字典,我将能够迭代数据并在需要时查找信息。
我搜索并找到了用于相同目的的xmltodict:
import xmltodict
with open(r'path\to\1.xml', encoding='utf-8', errors='ignore') as fd:
obj = xmltodict.parse(fd.read())
运行此操作会给我一个ordered dict
:
>>> obj
OrderedDict([('NewDataSet', OrderedDict([('Root', [OrderedDict([('Phonemic', 'and'), ('Phonetic', 'nd'), ('Description', None), ('Start', '0'), ('End', '8262')]), OrderedDict([('Phonemic', 'comfortable'), ('Phonetic', 'comfetebl'), ('Description', 'adj'), ('Start', '61404'), ('End', '72624')])])]))])
现在遗憾的是,这并没有使事情变得更简单,我不知道如何使用新的数据结构来实现程序。例如,访问nd
我必须写:
obj['NewDataSet']['Root'][0]['Phonetic']
这太荒谬了。我试图通过dict()
将它变成常规字典,但是当它嵌套时,内层仍然是有序的,我的数据是如此之大。
答案 0 :(得分:5)
如果你以obj['NewDataSet']['Root'][0]['Phonetic']
,IMO的身份访问它,那么你做得不对。
相反,您可以执行以下操作
obj = obj["NewDataSet"]
root_elements = obj["Root"] if type(obj) == OrderedDict else [obj["Root"]]
# Above step ensures that root_elements is always a list
for element in root_elements:
print element["Phonetic"]
即使这段代码看起来更长,但优点是一旦你开始处理足够大的xml,它就会更加紧凑和模块化。
PS:xmltodict
遇到了同样的问题。但是,使用xml.etree.ElementTree解析xml文件而不是解析xmltodict更容易使用,因为代码库更小,而且我不必处理xml模块的其他内容。
<强> 修改 强>
以下代码适用于我
import xmltodict
from collections import OrderedDict
xmldata = """<NewDataSet>
<Root>
<Phonemic>and</Phonemic>
<Phonetic>nd</Phonetic>
<Description/>
<Start>0</Start>
<End>8262</End>
</Root>
<Root>
<Phonemic>comfortable</Phonemic>
<Phonetic>comfetebl</Phonetic>
<Description>adj</Description>
<Start>61404</Start>
<End>72624</End>
</Root>
</NewDataSet>"""
obj = xmltodict.parse(xmldata)
obj = obj["NewDataSet"]
root_elements = obj["Root"] if type(obj) == OrderedDict else [obj["Root"]]
# Above step ensures that root_elements is always a list
for element in root_elements:
print element["Phonetic"]
答案 1 :(得分:1)
您实际上可以通过设置其他关键字参数来避免转换为OrderedDict:
[]
obj = xmltodict.parse(xmldata, dict_constructor=dict)
将关键字参数转发给parse
,_DictSAXHandler
默认设置为dict_constructor
。
答案 2 :(得分:0)
import xmltodict
from collections import OrderedDict
xmldata = """<NewDataSet>
<Root>
<Phonemic>and</Phonemic>
<Phonetic>nd</Phonetic>
<Description/>
<Start>0</Start>
<End>8262</End>
</Root>
<Root>
<Phonemic>comfortable</Phonemic>
<Phonetic>comfetebl</Phonetic>
<Description>adj</Description>
<Start>61404</Start>
<End>72624</End>
</Root>
</NewDataSet>"""
obj = xmltodict.parse(xmldata)
obj = obj["NewDataSet"]
root_elements = obj["Root"] if type(obj["Root"]) == list else [obj["Root"]]
# Above step ensures that root_elements is always a list
# Is obj["Root"] a list already, then use obj["Root"], otherwise make single element list.
for element in root_elements:
print element["Phonetic"]