从解析的XML文件中配对子元素和嵌套子元素的值

时间:2017-03-26 18:12:33

标签: python xml elementtree

我正在使用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>

我能够做的就是简单的部分,我已经能够深入了解我感兴趣的子元素并提取他们的文本信息。但是,一旦我尝试组织这些信息,我就会遇到麻烦,因为我无法弄清楚如何配对上述孩子的价值观。

这很重要,因为如果任意配对,它们就没有意义。 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,然后在适当的对中组织它们。后来的目标是将它们写入表中,保留这些配对。

1 个答案:

答案 0 :(得分:1)

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

<强>代码:

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,他们会非常光滑。它们是元组,也可以使用命名属性进行访问。以下是使用namedtuples的上面的循环。

奖金代码:

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.
相关问题