使用minidom在xml文件中获取嵌套元素的问题

时间:2014-11-27 02:55:33

标签: python xml xml-parsing minidom

我正在尝试在python中解析一个项目的“xml”文件。

我希望代码通过xml解析并获取每个过程的信息。这些信息将作为python字典返回。

具体来说,我将向下遍历每个Procedure元素,并获取有关其Data#名称和类型的信息。

目前,我的代码如下。

问题是Data2不是正确的对象类型,所以我无法横向进入Variable层 我不明白为什么我不能继续使用getElementsByTagName来浏览每一层。

在完整的代码中,我将为每个Data#执行此操作,并且我应该期望为过程指定“none”或空节点。然后应该期望代码处理它(除了检查Data2Element之外什么都没有时,不知道如何处理它)。很好,建议的解决方案使用另一种方法。

因此问题是如何在python中处理xml文档中的空节点。

注意:我无法控制文件格式,我有'标准'python 3.3模块,所以包括xml.dom和xml.etree,另外我有美丽的汤(但没有lxml) 。我无法安装'lxml'或其他任何尚未安装的东西。如果我的解决方案需要,我很乐意切换到其他已安装的模块之一。

filename = 'TestProc.xml'
from xml.dom import minidom

xmldoc = minidom.parse(filename)

procedureList = xmldoc.getElementsByTagName('Procedure')

varName=[]
varType=[]
for procElement in procedureList:
    Data2 = procElement.getElementsByTagName('Data2')
    varElements = Data2.getElementsByTagName('Variable')
    for varElemTmp in varElements:
        varName.append(varElemTmp.getAttribute('name'))
        varType.append(varElemTmp.getAttribute('type'))

以下是TestProc.xml的地方。

<?xml version="1.0" encoding="utf-8"?>
<ProcedureSet xmlns:xs="htt//www.w3.org/2001/XMLSchema">
<GlobalCode>
        <CodeBlock id="Code1">
</CodeBlock>
        <CodeBlock id="Code2">
</CodeBlock>
        <CodeBlock id="Code3">
</CodeBlock>
</GlobalCode>
    <Procedures>
        <Procedure id="Proc1" displayToUser="false" expectedType="Type1">
            <Description>Description1.</Description>
            <Data1 />
            <Data2 />
            <Data3 />
            <Data4 />
            <MainCode id="main">
Junk1
</MainCode>
        </Procedure>
        <Procedure id="Proc2" displayToUser="false" expectedType="Type2">
            <Description>Description2.</Description>
            <Data1 />
            <Data2>
                <Variable name="Var1" type="bool" causesChange="false">
                        <description>Description3</description>
                    </Variable>
            </Data2>
            <Data3>
                <Variable name="Var2" type="bool" causesChange="false">
                    <description>Description4</description>
                </Variable>
                <Variable name="Var3" type="int" causesChange="false">
                    <description>Description5</description>
                </Variable>
            </Data3>
            <Data4>
                <Variable name="Var4" type="link" />
                <Variable name="Var5" type="link" />
            </Data4>
            <MainCode id="main">
Junk2
</MainCode>
        </Procedure>
    </Procedures>
</ProcedureSet>

1 个答案:

答案 0 :(得分:1)

Data2是元素列表,而不是单个元素。您可以像这样修改代码:

for procElement in procedureList:
    ListOfData2 = procElement.getElementsByTagName('Data2')
    for Data2 in ListOfData2:
        varElements = Data2.getElementsByTagName('Variable')
        for varElemTmp in varElements:
            varName.append(varElemTmp.getAttribute('name'))
            varType.append(varElemTmp.getAttribute('type'))

如果切换到ElementTree,可以使用XPath语法保存自己的循环:

filename = 'TestProc.xml'
import xml.etree.ElementTree as ET

xmldoc = ET.parse(filename)

variables = xmldoc.findall(".//Procedure/Data2/Variable")

varName=[e.get('name') for e in variables]
varType=[e.get('type') for e in variables]

print varName, varType