Python - 当存在多个同名元素属性时如何编辑特定的XML元素内容?
Python - how to edit a specific XML element content when multiple element attributes of the same name exist?
我一直在尝试编辑包含多个同名元素内容的XML中的一个特定元素内容,但是设置元素属性所需的"for loop"总是会浏览整个部分并全部更改。
假设这是我的 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 循环始终更改特定嵌套中的最后一个属性。
由于我正在动态添加和编辑行,因此它会更改我添加的最后一行。
谢谢。
您可以使用 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中的一个特定元素内容,但是设置元素属性所需的"for loop"总是会浏览整个部分并全部更改。
假设这是我的 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 循环始终更改特定嵌套中的最后一个属性。 由于我正在动态添加和编辑行,因此它会更改我添加的最后一行。
谢谢。
您可以使用 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)