处理VOC标注XML执行remove操作报ValueError: x not in list如何解决
错误原因
Element.remove() 方法仅能删除当前节点的直接子节点,你尝试用根节点root删除属于<bndbox>子节点的xmin等标签,这些节点根本不是root的直接子节点,因此触发找不到节点的报错。
且你的需求是删除所有<part>标签及内部全部内容,不需要逐层处理内部节点,直接删除<part>节点本身即可。
修正后代码
import xml.etree.ElementTree as ET from PIL import Image for img, ann in zip(imgpath, AnnPath): sample_image = Image.open(img) # sample_image.show() with open(ann) as annot_file: print(''.join(annot_file.readlines())) tree = ET.parse(ann) root = tree.getroot() for neighbor in root.iter('object'): className = str(neighbor.find('name').text) print(className) # 先把当前object下的所有part节点存为列表,避免遍历中删除节点导致迭代异常 part_nodes = list(neighbor.iter('part')) for part_node in part_nodes: # 从直接父节点object中删除part节点,内部所有内容会同步被移除 neighbor.remove(part_node) # 若需要保存修改后的XML,取消注释下行即可 # tree.write(ann, encoding='utf-8')
额外说明
- 先将所有
<part>节点转成列表再遍历删除,是为了避免ET迭代器在遍历过程中节点结构变化导致漏删节点的问题 - 调用
neighbor.remove(part_node)时,neighbor是<part>的直接父节点<object>,可以正常完成删除操作,不需要单独处理<part>内部的子标签。
内容的提问来源于stack exchange,提问作者Yaman Afadar
相关产品推荐
相关产品推荐

