Python如何完全删除XML所有重复节点,现有代码仅能删除部分重复
问题原因
- 变量作用域错误:
prev变量定义在遍历<email>节点的循环外部,会跨不同<email>节点复用前一个节点的对比基准,逻辑不符合需求。 - 节点对比规则冗余:自定义的
elements_equal方法包含了对tail属性的校验,XML 中节点的tail存储的是标签后的空白字符(换行、缩进等),你测试用例中第四个<body>节点后接的是</email>标签,尾部缩进和前三个<body>不一致,导致第四个重复节点被判定为非重复节点,最终只删除了2个重复节点。 - 初始值不规范:
prev初始赋值为空字符串,首次对比时会出现节点和字符串做类型校验的情况,虽不影响运行但不符合逻辑规范。
修正后代码
tree = etree.parse(path) root = tree.getroot() def elements_equal(e1, e2): if type(e1) != type(e2): return False if e1.tag != e2.tag: return False if e1.text != e2.text: return False # 移除tail属性对比,排除尾部空白字符干扰 # if e1.tail != e2.tail: # return False if e1.attrib != e2.attrib: return False if len(e1) != len(e2): return False return all([elements_equal(c1, c2) for c1, c2 in zip(e1, e2)]) for page in root: elems_to_remove = [] # prev移到email节点遍历内部,每次处理新email时重置对比基准 prev = None for elem in page: if prev is not None and elements_equal(elem, prev): print("found duplicate: %s" % elem.text) elems_to_remove.append(elem) continue prev = elem for elem_to_remove in elems_to_remove: page.remove(elem_to_remove) # 输出时指定编码和XML声明,避免乱码 tree.write("clean.xml", encoding="UTF-8", xml_declaration=True)
修正效果说明
运行修正后代码,测试用例中第一个 <email> 节点下的4个重复 <body> 节点会保留1个,删除剩余3个,符合连续重复节点完全去重的需求。
内容的提问来源于stack exchange,提问作者christianjthomas
相关产品推荐
相关产品推荐

