Python - 当存在多个同名元素属性时,如何编辑特定的XML元素内容?

时间:2017-03-21 09:23:58

标签: python xml python-2.7 elementtree

我一直在尝试编辑XML中的一个特定元素内容,其中包含多个同名的元素内容,但设置元素属性所需的“for循环”将始终遍历整个部分并更改他们都是。

让我们说这是我的XML:

<SectionA>
    <element_content attribute="device_1" type="parameter_1" />
    <element_content attribute="device_2" type="parameter_2" />
</SectionA>

我目前正在使用带有此代码的ElementTree,当某个部分的元素内容具有不同的名称时,它可以正常工作,但它不适用于这种情况 - 名称相同。它只会将所有内容的属性更改为具有相同的值。

for element in root.iter(section):
    print element
    element.set(attribute, attribute_value)

如何访问特定元素内容并仅更改该内容?

请记住,我不知道element_content部分中当前存在的属性,因为我正在动态地将它们添加到用户的请求中。

修改: 感谢@leovp,我能够解决我的问题,并提出了这个解决方案:

for step in root.findall(section):
    last_element = step.find(element_content+'[last()]')

last_element.set(attribute, attribute_value)

这会导致for循环始终更改特定嵌套中的最后一个属性。 由于我正在动态添加和编辑行,这使它改变了我添加的最后一行。

谢谢。

1 个答案:

答案 0 :(得分:2)

您可以使用xml.etree提供的有限XPath支持:

>>> from xml.etree import ElementTree
>>> xml_data = """
... <SectionA>
...     <element_content attribute="device_1" type="parameter_1" />
...     <element_content attribute="device_2" type="parameter_2" />
... </SectionA>
... """.strip()
>>> tree = ElementTree.fromstring(xml_data)
>>> d2 = tree.find('element_content[@attribute="device_2"]')
>>> d2.set('type', 'new_type')
>>> print(ElementTree.tostring(tree).decode('utf-8'))
<SectionA>
    <element_content attribute="device_1" type="parameter_1" />
    <element_content attribute="device_2" type="new_type" />
</SectionA>

这里最重要的部分是XPath表达式,我们在其中找到一个名称和属性值的元素:

d2 = tree.find('element_content[@attribute="device_2"]')

更新:因为事先不知道有问题的XML数据。 您可以查询第一个,第二个,......,最后一个元素(索引从1开始):

tree.find('element_content[1]')
tree.find('element_content[2]')
tree.find('element_content[last()]')

但是既然你无论如何都要迭代元素,最简单的解决方案就是检查当前元素的属性:

for element in root.iter(section):
    if element.attrib.get('type') == 'parameter_2'):
        element.set(attribute, attribute_value)