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

问题描述:

我一直在试图编辑XML中的一个特定的元素内容,其中包含多个相同名称的元素内容,但设置元素属性所需的“for循环”将始终贯穿整个部分并更改它们所有。Python - 如何在存在多个同名元素属性时编辑特定的XML元素内容?

让我们说,这是我的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循环总是在发生变化的具体鸟巢最后一个属性。 由于我动态添加和编辑线条,这使得它改变了我添加的最后一个。

谢谢。

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

>>> 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) 
+0

嘿,非常感谢您的回答!不幸的是,我无法以这种方式进行搜索,因为我无法确定属性的值。 XML文件对我来说是“不可见的”,我应该可以动态编辑它。如果我想要更改1st/2nd element_conent,是否没有办法检查element_content [0]或类似的东西? –

+0

我用一些可能的解决方案更新了答案。 – leovp

+0

您提供的for循环没有帮助,因为正如我所说的,我无法确定位于元素内部的属性。然而,我确实使用了部分解决方案,主要是[last()]部分。我已经更新了原来的帖子。非常感谢你的协助! –