使用xml.etree.ElementTree嵌套XML标签及恢复XML声明的问题
解决XML标签嵌套错误与声明头丢失问题
问题说明
你期望生成的目标XML结构如下:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <Data> <Source Filename="C:\Data\Test01"> <Destination Filename="d:\Data\Test01.52829662.file"/> <Destination Filename="d:\Data\Test01.54123124.file"/> </Source> </Data>
但当前代码生成的XML存在两个问题:
Destination标签未嵌套在Source标签内部,直接成为Data的子元素;- 缺失XML声明头
<?xml version="1.0" encoding="UTF-8" standalone="no"?>。
你的错误代码:
import xml.etree.ElementTree as ET # Open the xml file xml = ET.parse(xml_name) data = {file:"C:\Data\Test01", ["d:\Data\Test01.52829662.file", "d:\Data\Test01.54123124.file"]} source_tag = [ET.SubElement(xml.getroot(), "Source") for name in data] destination_tag = [[ET.SubElement(xml.getroot(), "Destination") for trial in xml[name]] for name in xml.keys()]
生成的错误XML:
<Data> <Source Filename="C:\Data\Test01" /> <Destination Filename="d:\Data\Test01.52829662.file"/> <Destination Filename="d:\Data\Test01.54123124.file"/> </Data>
解决方案
1. 修正数据结构
原字典写法非法,需改为标准键值对格式,同时注意转义路径中的反斜杠:
data = { "source_path": "C:\\Data\\Test01", "destinations": [ "d:\\Data\\Test01.52829662.file", "d:\\Data\\Test01.54123124.file" ] }
2. 实现正确标签嵌套
创建Source标签后,将Destination标签作为其子元素添加,而非直接挂载到根节点:
# 读取现有XML文件 xml_tree = ET.parse(xml_name) root = xml_tree.getroot() # 创建Source标签并添加到根节点 source_tag = ET.SubElement(root, "Source", {"Filename": data["source_path"]}) # 遍历目标列表,将Destination嵌套到Source内部 for dest_path in data["destinations"]: ET.SubElement(source_tag, "Destination", {"Filename": dest_path})
3. 恢复XML声明头
ElementTree默认不写入声明头,需手动写入后再保存XML内容:
# 写入文件并包含声明头 with open(xml_name, "wb") as f: # 先写入XML声明 f.write(b'<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n') # 写入XML结构 xml_tree.write(f, encoding="UTF-8")
完整代码
import xml.etree.ElementTree as ET xml_name = "your_file.xml" # 替换为你的XML文件名 # 修正后的数据结构 data = { "source_path": "C:\\Data\\Test01", "destinations": [ "d:\\Data\\Test01.52829662.file", "d:\\Data\\Test01.54123124.file" ] } # 读取现有XML文件 xml_tree = ET.parse(xml_name) root = xml_tree.getroot() # 创建Source标签并添加到根节点 source_tag = ET.SubElement(root, "Source", {"Filename": data["source_path"]}) # 嵌套创建Destination标签 for dest_path in data["destinations"]: ET.SubElement(source_tag, "Destination", {"Filename": dest_path}) # 写入文件并包含XML声明 with open(xml_name, "wb") as f: f.write(b'<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n') xml_tree.write(f, encoding="UTF-8")
关键说明
- 路径转义:Windows路径中的
\必须写成\\,避免被Python解析为转义字符(如\T会被识别为制表符)。 - 层级控制:
ET.SubElement(parent, tag)会将新标签作为parent的子元素,确保嵌套关系正确。 - 声明头处理:通过手动写入字节形式的声明字符串,再调用
xml_tree.write(),保证最终XML包含完整的声明信息。
内容的提问来源于stack exchange,提问作者Nev Pires
相关产品推荐
相关产品推荐

