在Python中将XML解析为字典

3

我有以下的xml文件。我需要自动化地在不同的环境下查找/替换一些字符串,这些操作需要应用于一组文件。我正在使用Python 2.7进行开发。我需要传递环境名称并将XML读取到字典或数组中,然后可以使用它来查找/替换字符串。我尝试使用ElementTree,但是不确定如何构建包含每个环境的旧/新文本的字典。请给予建议...

     <?xml version="1.0" encoding="utf-8" ?>
    <Config>
    <Environment env="Support">
      <sitedir path="d:\Support_463\REST Elements\Sites"/>
      <workflowdir path="d:\Support_463\REST 
    Elements\Sites\Resources\Workflows"/>
      <sitereplacements>
        <text old="zz-dev" new="zz-supp"/>
        <text old="yhz" new="vr"/>
        <text old="ax7" new="sh66^"/>
      </sitereplacements>
      <workflowreplacements>
        <text old="zz-dev" new="zz-suppx"/>
        <text old="yhsxz" new="v*&9r"/>
        <text old="ax7" new="(()&4fg"/>
      </workflowreplacements>
</Environment>
<Environment env="Test">
      <sitedir path="d:\Test_463\REST Elements\Sites"/>
      <workflowdir path="d:\Test_463\REST Elements\Sites\Resources\Workflows"/>
      <sitereplacements>
        <text old="zz-dev" new="zz-test"/>
        <text old="yhz" new="vxxAr"/>
        <text old="ax7" new="s8%6^"/>
      </sitereplacements>
      <workflowreplacements>
        <text old="zz-dev" new="zz-testx"/>
        <text old="yhsxz" new="vr"/>
        <text old="ax7" new="$%^"/>
      </workflowreplacements>
</Environment>
<!--<Environment env="Preprod">
      <sitedir path=""/>
      <workflowdir path=""/>
      <sitereplacements>
        <text old="" new=""/>
        <text old="" new=""/>
        <text old="" new=""/>
      </sitereplacements>
      <workflowreplacements>
        <text old="" new=""/>       
        <text old="" new=""/>
        <text old="" new=""/>
      </workflowreplacements>-->
</Environment>


您从未关闭<Config>标签,因此这不是有效的XML。 - Graipher
2个回答

6
最简单的将XML转换为字典的方法是使用xmltodict模块。
示例:
import xmltodict
s = """<?xml version="1.0" encoding="utf-8" ?>
    <Config>
    <Environment env="Support">
      <sitedir path="d:\Support_463\REST Elements\Sites"/>
      <workflowdir path="d:\Support_463\REST 
    Elements\Sites\Resources\Workflows"/>
      <sitereplacements>
        <text old="zz-dev" new="zz-supp"/>
        <text old="yhz" new="vr"/>
        <text old="ax7" new="sh66^"/>
      </sitereplacements>
      <workflowreplacements>
        <text old="zz-dev" new="zz-suppx"/>
        <text old="yhsxz" new="v9r"/>
        <text old="ax7" new="(()4fg"/>
      </workflowreplacements>
</Environment>
<Environment env="Test">
      <sitedir path="d:\Test_463\REST Elements\Sites"/>
      <workflowdir path="d:\Test_463\REST Elements\Sites\Resources\Workflows"/>
      <sitereplacements>
        <text old="zz-dev" new="zz-test"/>
        <text old="yhz" new="vxxAr"/>
        <text old="ax7" new="s8%6^"/>
      </sitereplacements>
      <workflowreplacements>
        <text old="zz-dev" new="zz-testx"/>
        <text old="yhsxz" new="vr"/>
        <text old="ax7" new="$%^"/>
      </workflowreplacements>
</Environment>
</Config>
"""
print xmltodict.parse(s)

输出:

OrderedDict([(u'Config', OrderedDict([(u'Environment', [OrderedDict([(u'@env', u'Support'), (u'sitedir', OrderedDict([(u'@path', u'd:\\Support_463\\REST Elements\\Sites')])), (u'workflowdir', OrderedDict([(u'@path', u'd:\\Support_463\\REST      Elements\\Sites\\Resources\\Workflows')])), (u'sitereplacements', OrderedDict([(u'text', [OrderedDict([(u'@old', u'zz-dev'), (u'@new', u'zz-supp')]), OrderedDict([(u'@old', u'yhz'), (u'@new', u'vr')]), OrderedDict([(u'@old', u'ax7'), (u'@new', u'sh66^')])])])), (u'workflowreplacements', OrderedDict([(u'text', [OrderedDict([(u'@old', u'zz-dev'), (u'@new', u'zz-suppx')]), OrderedDict([(u'@old', u'yhsxz'), (u'@new', u'v9r')]), OrderedDict([(u'@old', u'ax7'), (u'@new', u'(()4fg')])])]))]), OrderedDict([(u'@env', u'Test'), (u'sitedir', OrderedDict([(u'@path', u'd:\\Test_463\\REST Elements\\Sites')])), (u'workflowdir', OrderedDict([(u'@path', u'd:\\Test_463\\REST Elements\\Sites\\Resources\\Workflows')])), (u'sitereplacements', OrderedDict([(u'text', [OrderedDict([(u'@old', u'zz-dev'), (u'@new', u'zz-test')]), OrderedDict([(u'@old', u'yhz'), (u'@new', u'vxxAr')]), OrderedDict([(u'@old', u'ax7'), (u'@new', u's8%6^')])])])), (u'workflowreplacements', OrderedDict([(u'text', [OrderedDict([(u'@old', u'zz-dev'), (u'@new', u'zz-testx')]), OrderedDict([(u'@old', u'yhsxz'), (u'@new', u'vr')]), OrderedDict([(u'@old', u'ax7'), (u'@new', u'$%^')])])]))])])]))])

很好的简明回答。太多人在类似问题上把事情搞得过于复杂了。完美地解决了问题。 - Wev

0

2
这是一条注释,不是一个答案。 - eagle
感谢回复。我现在可以成功使用ElementTree来读取它了。但是,我在使用xpath查找区分大小写的值时遇到了困难xmlEl = root.find('.//Environment[@env="%s"]' %env)。我需要将@env转换为小写字母,然后再使用find。 - user1603842

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接