用有序字典解析xml文件

2024-04-23 06:47:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个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>标记匹配,并从<Phonemic>部分返回and。我想,如果我能将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()把它变成一个常规字典,但是由于它是嵌套的,所以内部层保持有序,而且我的数据非常大。


Tags: and文件objrootdescriptionxmlstartend
3条回答

通过设置其他关键字参数,实际上可以避免转换为OrderedDict:

obj = xmltodict.parse(xmldata, dict_constructor=dict)

parse正在将关键字参数转发到_DictSAXHandlerdict_constructor默认设置为OrderedDict

Mu的答案对我很有用,我唯一需要改变的是复杂的确保根元素始终是一个列表步骤

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"]

如果您以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,它将变得更加紧凑和模块化。

注:我对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"]

相关问题 更多 >