You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 08:45:03