使用ElementTree为XML添加子元素并保存的格式问题
问题与解决方案
问题描述
参考过StackOverflow同类问题后仍无法解决:基于XML模板在filePaths节点下添加子元素,要求保留XML声明、命名空间,且子元素排版规范,但当前代码生成的XML缺失声明与命名空间,子元素排版混乱。
输入XML文件
<?xml version="1.0" encoding="utf-8"?> <MaxQuantParams xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <filePaths> <!-- <string>/PATH/TO/RAW/FILE</string> --> </filePaths> </MaxQuantParams>
期望输出XML文件
<?xml version="1.0" encoding="utf-8"?> <MaxQuantParams xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <filePaths> <string>file1.raw</string> <string>file2.raw</string> </filePaths> </MaxQuantParams>
尝试的Python代码
import xml.etree.ElementTree as ET import copy files = ["file1.raw", "file2.raw"] # 读取XML模板配置文件 config_template = ET.parse("input.xml") # 创建XML配置文件 config = copy.deepcopy(config_template) root = config.getroot() file_paths = root.find(".//filePaths") for file in files: child = ET.SubElement(file_paths, "string") child.text = file # 保存配置文件到输出目录 tree = ET.ElementTree(root) tree.write("out.xml", encoding="utf-8")
实际输出XML
<MaxQuantParams> <filePaths> <string>file1.raw</string><string>file2.raw</string></filePaths> </MaxQuantParams>
解决代码
import xml.etree.ElementTree as ET from xml.dom import minidom files = ["file1.raw", "file2.raw"] # 注册命名空间,防止输出时丢失 ET.register_namespace('xsd', 'http://www.w3.org/2001/XMLSchema') ET.register_namespace('xsi', 'http://www.w3.org/2001/XMLSchema-instance') # 读取XML模板 tree = ET.parse("input.xml") root = tree.getroot() file_paths = root.find(".//filePaths") # 移除原有的注释占位符(可选操作) for node in list(file_paths): if isinstance(node, ET.Comment): file_paths.remove(node) # 添加新的string子元素 for file in files: string_elem = ET.SubElement(file_paths, "string") string_elem.text = file # 格式化XML输出,实现规范排版 def prettify_xml(element): raw_xml = ET.tostring(element, encoding='utf-8') dom_tree = minidom.parseString(raw_xml) return dom_tree.toprettyxml(indent=" ", encoding='utf-8').decode('utf-8') # 写入输出文件 with open("out.xml", "w", encoding='utf-8') as output_file: output_file.write(prettify_xml(root))
关键修复点
- 保留命名空间:通过
ET.register_namespace显式注册原XML中的命名空间,避免输出时丢失命名空间定义。 - 保留XML声明:利用
minidom的toprettyxml自动生成包含编码信息的XML声明。 - 规范排版:通过
prettify_xml函数格式化XML,设置统一缩进,让子元素排版整齐;同时可选移除原注释节点,清理输出内容。
内容的提问来源于stack exchange,提问作者pklein
相关产品推荐
相关产品推荐

