必须用 lxml.etree.ElementTree.write() 方法写入 XML 文件,传 encoding="utf-8" 和 xml_declaration=True 以确保中文正常、生成标准 XML 声明,避免用字符串化或标准库 write。

lxml.etree.ElementTree 写入 XML 文件用哪个方法
直接用 tree.write(),别用 ElementTree.write()(标准库那个),否则会丢命名空间、编码混乱、自闭合标签处理错。lxml 的 write() 是真正支持完整 XML 特性的入口。
- 必须传
encoding="utf-8",否则默认 ASCII,中文变 ? 或报错 - 加
xml_declaration=True才能写出<?xml version='1.0' encoding='utf-8'?> - 如果元素含命名空间,得配
method="xml"(默认就是,但显式写更稳) - 别用
open(...).write(str(tree))—— 字符串化会破坏 etree 对 CDATA、特殊字符、前导空格的控制
写入时中文乱码或 UnicodeEncodeError 怎么办
根本原因是没指定编码,或系统默认编码干扰。lxml 不读取环境 locale,全靠你显式传参。
-
tree.write("out.xml", encoding="utf-8", xml_declaration=True)是安全底线 - 如果目标环境强制 GBK(比如老 Windows 脚本),就改用
encoding="gbk",但注意 Python 3 中 gbk 不能处理所有 Unicode 字符,可能回退失败 - 避免用
open("out.xml", "w").write(etree.tostring(...).decode())——tostring()返回 bytes,decode() 容易错配编码,直接 write bytes 更可靠
etree.tostring() 和 tree.write() 选哪个
要落地成文件,无条件选 tree.write();只做内存拼接或调试看结构,才用 etree.tostring()。
-
tree.write()自动处理换行缩进(除非你关掉pretty_print=False),tostring()默认不缩进 -
tostring()返回bytes,常被误当成 str 去 print 或拼接,引发TypeError: can't concat bytes to str - 想写入带 BOM 的 UTF-8 文件?
tree.write()不支持,得先tostring(..., encoding="utf-8"),再手动加 BOM:b"\xef\xbb\xbf" + xml_bytes
写入后 XML 格式错乱(如标签挤在一起、属性换行)
不是 bug,是 lxml 默认不美化输出。它优先保证语义正确性,格式只是副作用。
立即学习“Python免费学习笔记(深入)”;
- 加
pretty_print=True参数可启用缩进,但仅对子元素生效,根元素前无换行 - 如果已有文本节点(
elem.text)含空白,pretty_print会尊重它 —— 这常导致“缩进失效”,其实是内容本身带了空格 - 需要严格控制格式(比如和 legacy 系统对接),别依赖
pretty_print,改用lxml.etree.tounicode()+ 正则或第三方库如xmlformatter - 注意:开启
pretty_print=True会轻微降低性能,大数据量 XML 写入时可关掉
encoding 和 xml_declaration 这两个参数,一漏就卡在中文或解析失败上。










