Python删除XML节点需通过xml.etree.ElementTree加载后,由父节点调用remove()方法移除子节点;必须先定位父元素和目标子元素,不可对目标节点自身调用remove();支持find()/findall()匹配或iter()遍历,条件删除需结合XPath属性筛选,保存时可用ET.indent()美化格式。

Python删除XML中的节点,核心是用 xml.etree.ElementTree(标准库)加载、遍历并调用 remove() 方法。关键在于准确获取父节点,再从其子节点列表中移除目标节点——ElementTree不支持直接“删自己”,必须由父节点操作。
使用 remove() 删除指定子节点
这是最常用、最稳妥的方式。需先定位父元素,再找到要删的子元素,最后调用 parent.remove(child):
- 不能对目标节点自身调用
node.remove()(会报错) - 建议用
find()或findall()精准匹配,避免误删 - 若节点有多个同名子节点,
find()只删第一个;用findall()+ 循环可批量删
示例:删掉所有 节点
import xml.etree.ElementTree as ETtree = ET.parse("book.xml") root = tree.getroot()
删除所有 price 子节点(在每个 book 下)
for book in root.findall("book"): for price in book.findall("price"): book.remove(price)
tree.write("book_clean.xml", encoding="utf-8", xml_declaration=True)
用 XPath 定位后删除(更灵活)
当目标节点嵌套深或路径复杂时,XPath 表达式比多层 find() 更清晰。注意:remove() 仍需作用于父节点,所以得反推父节点:
立即学习“Python免费学习笔记(深入)”;
- 用
tree.xpath()?不行——标准 ElementTree 不支持 XPath 删除,仅支持基础语法(如.//price) - 正确做法:用
find()配合相对路径,或先用xpath找到节点,再用getparent()(需换用 lxml 库) - 若坚持用标准库,可用
iter()遍历所有节点,记录父节点和目标节点配对关系
纯 ElementTree 示例(不依赖 lxml):
# 删除所有层级下的 price 节点(不管在哪一层)
for price in root.iter("price"):
parent = root
# 手动找 parent(简化版:只查一级子节点的父节点)
for child in root:
if price in list(child):
parent = child
break
if price in list(parent):
parent.remove(price)
删除带条件的节点(如属性匹配)
常需按属性值筛选,比如删掉 id="102" 的 book:
- 用
find('book[@id="102"]')直接定位目标节点 - 确认该节点存在且有父节点后再删,避免 AttributeError
- 属性值含变量时,用 f-string 或
format()拼接 XPath(注意引号转义)
target_book = root.find('book[@id="102"]')
if target_book is not None:
root.remove(target_book) # 因为 book 是 root 的直接子节点
保存时保留格式(缩进与换行)
默认 tree.write() 输出无缩进,像机器写的。如需人眼可读:
- Python 3.9+ 可用
ET.indent(tree)自动加缩进 - 旧版本可用第三方工具如
xml.dom.minidom重排格式 - 写入时设
encoding="utf-8"和xml_declaration=True,确保中文和声明正常
if hasattr(ET, 'indent'): # Python 3.9+
ET.indent(tree, space=" ")
tree.write("output.xml", encoding="utf-8", xml_declaration=True)
