【问题标题】:Python - how to edit a specific XML element content when multiple element attributes of the same name exist?Python - 当存在多个同名元素属性时如何编辑特定的 XML 元素内容?
【发布时间】:2017-03-21 09:23:57
【问题描述】:

我一直在尝试编辑包含多个同名元素内容的 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 循环始终更改特定嵌套中的最后一个属性。 由于我是动态添加和编辑行,这使它改变了我添加的最后一个。

谢谢。

【问题讨论】:

    标签: python xml python-2.7 elementtree


    【解决方案1】:

    您可以使用 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)
    

    【讨论】:

    • 您好,非常感谢您的回答!不幸的是,我无法以这种方式进行搜索,因为我无法判断属性的值是什么。 XML 文件对我来说是“不可见的”,我应该能够动态编辑它。如果我想更改第一个/第二个 element_conent,有没有办法检查 element_content[0] 或类似的东西?
    • 我用几个可能的解决方案更新了答案。
    • 您提供的 for 循环没有帮助,因为正如我所说,我无法确定位于元素内部的属性。但是,我确实最终使用了您的解决方案的一部分,主要是 [last()] 部分。我已经用更改更新了我的原始帖子。非常感谢您的帮助!
    猜你喜欢
    • 2022-06-23
    • 1970-01-01
    • 2012-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-26
    • 2015-01-11
    相关资源
    最近更新 更多