使用python从具有相同父标记的子XML标记中提取值

时间:2018-11-21 20:16:14

标签: python xml

我正在尝试使用python从XML文件中提取编号。我曾经能够使用getElementsByTagName('RollNumber')检索适当的元素。

具有相同子标记名称的父标记现已添加到XML生成中。当我运行脚本时,出现错误,指出元素实例没有属性'data'

<RollNumbers>
    <RollNumber>
        <RollNumber>1234567891011120000</RollNumber>
    </RollNumber>
</RollNumbers>

我在下面附加了我的脚本:

import arcpy,sys,os,xml.dom.minidom

arcpy.env.overwriteOutput = True

fname = arcpy.GetParameterAsText(0)
fxml = open(fname, 'r')

if fxml != None:
    XMLData = fxml.read()
    fxml.close()

dom = xml.dom.minidom.parseString(XMLData)
node = dom.documentElement

rollTag = dom.getElementsByTagName('RollNumber')

RollNums = []
for RollNumber in rollTag:
    nodes = RollNumber.childNodes
    for node in nodes:
        arn = node.data[:15]
        arcpy.AddMessage(arn)
        RollNums.append(arn)

rolllen = len(RollNums)
arcpy.AddMessage(rolllen)

1 个答案:

答案 0 :(得分:0)

这里的问题是,您假设RollNumber元素的所有子节点都是Text节点。但是,XML文档中的父RollNumber元素有另一个元素作为其子元素,因此您不能为元素返回data

处理问题的一种方法是替换行

rollTag = dom.getElementsByTagName('RollNumber')

使用

rollTag = [ element for element in dom.getElementsByTagName('RollNumber')
                     if not element.getElementsByTagName('RollNumber') ]

dom.getElementsByTagName('RollNumber')返回带有标签名RollNumber的所有元素。对于每个这样的元素,我们找到也具有名称RollNumber的子元素。如果找到任何节点,则element是父节点,并从返回到rollTag的列表中排除。 rollTag因此最终只包含子RollNumber子节点。

或者,您可以替换行

        arn = node.data[:15]
        arcpy.AddMessage(arn)
        RollNums.append(arn)

使用

        if isinstance(node, xml.dom.minidom.Text) and node.data.strip():
            arn = node.data[:15]
            arcpy.AddMessage(arn)
            RollNums.append(arn)

这将检查RollNumber元素的子节点是否为Text节点,并检查其是否包含空格。在示例XML文档中,父RollNumber元素有两个子节点,这两个子节点都是仅包含空格的Text节点,但是您想忽略它们。

如果要读取的数据仅位于最里面的RollNumber元素中,则这两种方法都应处理任意数量的嵌套RollNumber元素。如果父节点也包含文本,则它们的行为会有所不同,例如:

<RollNumbers>
    <RollNumber>
        <RollNumber>1234567891011120000</RollNumber>
        ABCDEFG
    </RollNumber>
</RollNumbers>

第一种方法只会返回123456789101112,但是第二种方法也会获取文本ABCDEFG