如何移除XML子标签并基于指定标签拆分生成多个新XML文件
问题1:创建符合要求的映射XML文件
实现逻辑如下:
- 先提取原XML中所有公共的
<SOURCE>、<TARGET>节点,这两个标签是所有映射文件通用的依赖 - 遍历原文件中的2个
<MAPPING>标签,每个标签单独对应一个m_开头的输出文件 - 每个映射文件保留和原XML一致的根节点、FOLDER节点结构,将公共的SOURCE、TARGET和当前遍历到的MAPPING塞入FOLDER节点后写入对应文件即可
示例代码(用lxml实现,更适合XML节点操作):
from lxml import etree # 读取原文件 tree = etree.parse('input.xml') root = tree.getroot() # 两个映射文件对应文件名,可根据实际MAPPING的属性调整匹配规则 map_filenames = ['m_demo_trans_agg.XML', 'm_demo_trans_exp.XML'] # 提取所有SOURCE、TARGET节点 folder_node = root.find('./FOLDER') sources = folder_node.findall('./SOURCE') targets = folder_node.findall('./TARGET') mappings = folder_node.findall('./MAPPING') # 逐个生成映射文件 for idx, mapping in enumerate(mappings): # 复制根节点结构,避免修改原节点 new_root = etree.Element(root.tag, root.attrib) new_folder = etree.SubElement(new_root, folder_node.tag, folder_node.attrib) # 拷贝SOURCE、TARGET节点 for s in sources: new_folder.append(etree.deepcopy(s)) for t in targets: new_folder.append(etree.deepcopy(t)) # 拷贝当前MAPPING节点 new_folder.append(etree.deepcopy(mapping)) # 写入文件 etree.ElementTree(new_root).write(map_filenames[idx], encoding='utf-8', xml_declaration=True)
问题2:代码残留标签的原因和修复
问题原因
你在使用iter()遍历子节点的同时执行remove()操作,会动态改变节点的子节点序列,导致迭代器的索引偏移,部分节点会被跳过遍历,因此出现漏删的情况。
修复方案
不要在遍历过程中删除节点,先把所有待删除的节点收集到列表中,遍历完成后统一删除即可。修复后的代码如下:
标准库xml.etree.ElementTree版本
import xml.etree.ElementTree as ET tree = ET.parse('input.xml') root = tree.getroot() target_node_first_parent = 'FOLDER' target_nodes = ['SOURCE', 'TARGET', 'MAPPING'] for node in root.iter(target_node_first_parent): # 先收集所有待删除的节点 to_remove = [] for subnode in node.iter(): if subnode.tag in target_nodes: to_remove.append(subnode) # 统一删除 for sub in to_remove: node.remove(sub) out_tree = ET.ElementTree(root) out_tree.write('wf_m_demo_trans_agg_exp.XML', encoding='utf-8', xml_declaration=True)
更简便的lxml版本
from lxml import etree tree = etree.parse('input.xml') for tag in ['SOURCE', 'TARGET', 'MAPPING']: # 直接查找所有对应标签并删除 for node in tree.xpath(f'//FOLDER/{tag}'): node.getparent().remove(node) tree.write('wf_m_demo_trans_agg_exp.XML', encoding='utf-8', xml_declaration=True)
内容的提问来源于stack exchange,提问作者usr_lal123
相关产品推荐
相关产品推荐

