基于Python按重复id_user拆分XML并保留原Schema的技术问询
解决方案:按唯一
id_user拆分XML文件 看起来你已经搞定了重复id的识别部分,接下来咱们直接解决拆分XML文件的问题。我会基于你现有的代码,扩展出完整的实现逻辑,保证生成的每个文件都符合原Schema,且每个文件里的facturic节点都是唯一的id_user。
整体思路
- 先将所有
facturic节点按id_user分组,方便后续分配 - 统计每个
id_user的节点数量,找到最大的那个值,这就是我们需要生成的文件总数 - 循环创建每个输出文件,依次从每个
id_user的节点列表中取出一个节点(如果还有剩余),放入当前文件的ROOT节点下,确保每个文件里的id_user不重复
完整实现代码
import os from xml.etree import ElementTree from collections import defaultdict def split_xml_by_unique_userid(fullpath, output_dir="split_output"): # 创建输出目录(如果不存在) os.makedirs(output_dir, exist_ok=True) # 解析原XML文件 dom = ElementTree.parse(fullpath) root = dom.getroot() findNode = 'facturic' findAttr = 'id_user' # 1. 按id_user分组所有facturic节点 user_nodes = defaultdict(list) for node in root.findall(findNode): user_id = node.attrib.get(findAttr) if user_id: # 确保id_user存在的节点才处理 user_nodes[user_id].append(node) # 2. 确定需要生成的文件总数(最大重复次数) max_count = max(len(nodes) for nodes in user_nodes.values()) if user_nodes else 0 # 3. 生成每个输出文件 for file_idx in range(max_count): # 创建新的ROOT节点,保持原Schema结构 new_root = ElementTree.Element("ROOT") # 为当前文件分配每个id_user的第file_idx个节点(如果存在) for user_id, nodes in user_nodes.items(): if file_idx < len(nodes): # 复制节点属性和子节点,避免修改原DOM结构 new_node = ElementTree.Element(findNode, attrib=nodes[file_idx].attrib) for child in nodes[file_idx]: new_node.append(child) new_root.append(new_node) # 生成XML文件,保留原编码和声明 tree = ElementTree.ElementTree(new_root) output_path = os.path.join(output_dir, f"output_{file_idx+1}.xml") with open(output_path, 'wb') as f: tree.write(f, encoding='utf-8', xml_declaration=True) print(f"已生成文件: {output_path}") # 调用示例(替换成你的输入XML路径) if __name__ == "__main__": input_xml_path = "your_input_file.xml" split_xml_by_unique_userid(input_xml_path)
代码关键说明
- 用
collections.defaultdict简化节点分组逻辑,比普通字典更高效 - 复制节点时不仅复制
id_user属性,还会完整复制子节点(比如artfacturic),确保原XML结构完全保留 - 自动创建输出目录,避免因路径不存在报错
- 输出文件按
output_1.xml、output_2.xml命名,清晰区分批次 - 写入时保留UTF-8编码和XML声明,和原文件格式完全一致
效果示例
针对你提供的输入XML:
<?xml version="1.0" encoding="utf-8" ?> <ROOT> <facturic id_user="18446195"><artfacturic/></facturic> <facturic id_user="18446195"><artfacturic/></facturic> <facturic id_user="34259554"><artfacturic/></facturic> </ROOT>
会生成2个符合要求的文件:
output_1.xml包含id_user="18446195"的第一个节点和id_user="34259554"的节点output_2.xml包含id_user="18446195"的第二个节点
每个文件内部的id_user都是唯一的,且完全符合原Schema结构。
内容的提问来源于stack exchange,提问作者Dumitru Daniel
相关产品推荐
相关产品推荐

