Python中向XML节点添加同名子节点时值重复问题求助
解决ElementTree重复添加节点后值全部覆盖的问题
问题原因
你一直在复用同一个tsk_var节点对象,每次循环只是修改它的name和value文本,然后将它追加到variables节点中。但ElementTree在追加节点时,并不会复制节点实例,只是添加对原节点的引用。所以最终所有<variable>节点实际上指向的都是同一个对象,自然会显示最后一次修改的键值对。
修正方案
每次循环都创建一个全新的<variable>节点,确保每个节点都是独立的对象,这样修改内容时不会互相影响。
方案一:在循环内通过字符串解析创建节点
import json import xml.etree.ElementTree as ET # 假设task_name已定义 task_name = "your_task_name" task_vars = '{"BNS_DT": "20220831","DWH_BD": "dwh_bd=2022-08-31","LAYR_CD": "STG"}' payload = ET.fromstring(f"""<task-launch><variables></variables><name>{task_name}</name></task-launch>""") tsk_vars = json.loads(task_vars) variables_node = payload.find('variables') for name, value in tsk_vars.items(): # 每次循环生成新的variable节点 tsk_var = ET.fromstring("""<variable><name></name><value></value></variable>""") # 直接查找name和value节点并赋值,不用循环遍历 tsk_var.find('name').text = name tsk_var.find('value').text = value print('to be added') print(ET.tostring(tsk_var, encoding='unicode')) variables_node.append(tsk_var) # 查看最终结果 print(ET.tostring(payload, encoding='unicode', pretty_print=True))
方案二:用ElementTree API直接创建节点(推荐)
这种方式更直观,避免字符串解析的额外开销:
import json import xml.etree.ElementTree as ET task_name = "your_task_name" task_vars = '{"BNS_DT": "20220831","DWH_BD": "dwh_bd=2022-08-31","LAYR_CD": "STG"}' payload = ET.fromstring(f"""<task-launch><variables></variables><name>{task_name}</name></task-launch>""") tsk_vars = json.loads(task_vars) variables_node = payload.find('variables') for name, value in tsk_vars.items(): # 创建根节点variable variable = ET.Element('variable') # 创建子节点name并设置文本 name_node = ET.SubElement(variable, 'name') name_node.text = name # 创建子节点value并设置文本 value_node = ET.SubElement(variable, 'value') value_node.text = value # 追加到variables节点 variables_node.append(variable) # 打印最终XML print(ET.tostring(payload, encoding='unicode', pretty_print=True))
最终效果
修正后生成的XML会正确显示每个键值对对应的<variable>节点:
<task-launch> <variables> <variable> <name>BNS_DT</name> <value>20220831</value> </variable> <variable> <name>DWH_BD</name> <value>dwh_bd=2022-08-31</value> </variable> <variable> <name>LAYR_CD</name> <value>STG</value> </variable> </variables> <name>your_task_name</name> </task-launch>
内容的提问来源于stack exchange,提问作者JanFi86
相关产品推荐
相关产品推荐

