child 和嵌套 child 元素的配对值来自已解析的 XML 文件

Pairing values of a child and nested child element from parsed XML files

我正在使用 Python 和 elementTree 来尝试解析一些 XML 文件,因为这些文件已被证明是我所使用的一些更好的工具阅读。

我要整理的 XML 文档是这种形式的:

<data>
 <property name="AText">
  <property value="BText">
   <property name="Id" value="DEVICE"/> #Pairing this value...
   <property name="CText" value="text">
     <property name="Value" value="This is a device."/> #...with this value is 
                                                         #proving problematic
   </property>
  </property>
  <property value="BText">
   <property name="Id" value="BRICK"/>
   <property name="CText" value="text">
     <property name="Value" value="This is a brick."/>
   </property>
   </property>
  </property>
</data>

我能做的是简单的部分,我能够深入到我感兴趣的 child 元素并提取它们的文本信息。然而,一旦我尝试组织这些信息,我就遇到了麻烦,因为我不知道如何配对上面指出的 children 的值。

这很重要,因为如果任意配对它们就没有意义。 Id 元素值的文本实际上是 Value 元素值的 ID。

目前,我的代码是:

import xml.etree.ElementTree as ET

tree = ET.parse('sample2.exml')
root = tree.getroot()

shrt = 0
txt = 0
save = {"ID:" : shrt, "Desc.:" : txt}

for y in root.findall("./Property//*[@name='Id']"):
    shrt = y.get('value')
    save["ID:"] = shrt

for x in root.findall(".//*[@name='CText']/Property"):
    txt = x.get('value')
    save["Desc.:"] = txt

print(save)

一旦你获得更多对,这就会崩溃。我已经尝试过列表,但这是我在寻找解决方案时没有放弃的最快(也是最干净)的代码。

我的主要目标只是解析这些元素的 XML,然后将它们组织成适当的对。后来的目标是可能将它们写入 table,保留这些配对。

配对属性的关键是同时处理它们。这段代码循环查找 属性 节点,然后使用子树的那部分继续查找所需的元素。

代码:

import xml.etree.ElementTree as ET

tree = ET.parse(xml_data)
root = tree.getroot()

results = []
for prop in root.findall(".//property/[@value='BText']"):
    results.append((
        prop.find(".//property/[@name='Id']").get('value'),
        prop.find(".//property/[@name='Value']").get('value'),
    ))

print(results)

测试数据:

from io import StringIO

xml_data = StringIO(u"""
    <data>
      <property name="AText">
        <property value="BText">
          <property name="Id" value="DEVICE"/> 
          <property name="CText" value="text"/>
          <property name="Value" value="This is a device."/>
        </property>
        <property value="BText">
          <property name="Id" value="BRICK"/>
          <property name="CText" value="text"/>
          <property name="Value" value="This is a brick."/>
        </property>
      </property>
    </data>
""")

结果:

[('DEVICE', 'This is a device.'), ('BRICK', 'This is a brick.')]

Python 很有趣:

作为跟进,如果您不熟悉 namedtuple,它们会非常流畅。它们是元组,也可以使用命名属性进行访问。这是上面使用命名元组的循环。

红利代码:

from collections import namedtuple
ItemDesc = namedtuple('ItemDesc', 'shrt txt')

results = []
for prop in root.findall(".//property/[@value='BText']"):
    results.append(ItemDesc(
        shrt=prop.find(".//property/[@name='Id']").get('value'),
        txt=prop.find(".//property/[@name='Value']").get('value'),
    ))

for item in results:
    print("shrt={}, txt={}".format(item.shrt, item.txt))

奖金结果:

shrt=DEVICE, txt=This is a device.
shrt=BRICK, txt=This is a brick.