批量修改xml需备份原文件,用elementtree时显式设置write参数并手动缩进,遍历用iter()而非findall(),属性操作用get/set方法,读取指定utf-8编码,路径用pathlib,禁用dtd解析,命名空间需显式声明。

能批量改,但别直接用 xml.etree.ElementTree 的 write() 覆盖原文件——默认不保留注释、缩进和声明,一跑就“毁格式”。
用 xml.etree.ElementTree 改属性前先备份并控制输出格式
很多人写完 tree.write() 发现 XML 变成一行、注释没了、<?xml version="1.0" encoding="utf-8"?> 消失了。这不是 bug,是默认行为。
- 务必在
tree.write()里显式传参:encoding="utf-8"、xml_declaration=True、method="xml" - 缩进需手动处理:Python 3.9+ 可用
xml.etree.ElementTree.indent(tree);旧版本得自己写递归缩进函数或换lxml - 修改前先
shutil.copy(src, src + ".bak"),防止批量写坏一堆文件
遍历所有匹配节点时,别只靠 findall() ——它不支持跨层级通配
findall("item") 只查子节点,嵌套深的(比如 <root><a><b><item></item></b></a></root>)会漏掉。
- 用
iter():它遍历整棵树,for elem in root.iter("item"):就能拿到所有<item></item> - 要按属性筛选?用
if elem.get("status") == "pending":,别写elem.attrib["status"]——键不存在会抛KeyError - 改值统一用
elem.set("status", "done"),不是elem.attrib["status"] = "done"(后者绕过内部状态管理,某些场景下失效)
批量处理多个 XML 文件时,路径和编码容易出错
常见报错:UnicodeDecodeError: 'gbk' codec can't decode byte 0xad 或 ParseError: not well-formed (invalid token)。
立即学习“Python免费学习笔记(深入)”;
- 读文件必须指定编码:
tree = ET.parse(path, parser=ET.XMLParser(encoding="utf-8"));没声明 encoding 容易崩在中文或特殊符号上 - 路径别硬写
"./data/*.xml",用pathlib.Path("data").glob("*.xml")更稳,自动处理斜杠和空格 - 遇到 DTD 或外部实体(比如含
..>),默认解析器会报错,加parser=ET.XMLParser(resolve_entities=False)
真正麻烦的是混合了命名空间的 XML——{http://example.com/ns}item 这种写法会让 iter("item") 失效,得用 iter("{http://example.com/ns}item") 或预定义 namespace dict。这点很多人改到一半才发现全没命中。










