高效生成大型XML文件应采用流式写入:用xml.sax.saxutils.XMLGenerator实现内存恒定的轻量输出,或用lxml.etree.XMLFile实现高速、低内存的边构边写,避免全量加载与字符串拼接。

直接用字符串拼接或常规 xml.etree.ElementTree 构建大型 XML 文件效率低、内存占用高,尤其当数据量达百万级节点时容易 OOM 或卡死。高效拼接的核心是:**流式生成 + 避免全量加载 + 复用底层写入器**。
用 xml.sax.saxutils.XMLGenerator 流式写入
这是最轻量、内存最可控的方式,适合“拼接多个已知结构的 XML 片段”或“边查库边生成”。它不解析也不保存树,只按需输出格式化标签。
- 导入
xml.sax.saxutils.XMLGenerator和xml.sax.xmlreader.AttributesImpl - 用
StringIO或文件对象初始化生成器,设置encoding='utf-8' - 手动调用
startElement()、characters()、endElement()输出内容 - 无需构建任何 Element 对象,每行写入即刷盘,内存恒定在 KB 级
用 lxml.etree.XMLFile(推荐用于大文件拼接)
lxml 的 XMLFile 是专为海量 XML 写入设计的上下文管理器,支持边构建边写入,比原生 ElementTree 快 3–5 倍,且自动处理命名空间和转义。
- 安装:
pip install lxml - 用
with XMLFile(open('out.xml', 'wb')) as xf:开启写入 - 用
xf.write_element(elem)直接写入已构建的etree.Element,内部自动 flush - 可配合
iterparse读取其他 XML 文件并逐段写入,实现“零内存拼接”
避免常见低效操作
这些做法看似直观,实则会拖垮性能:
立即学习“Python免费学习笔记(深入)”;
- 不用
str(root)或tostring()把整棵树转字符串再拼接——会复制全部内容到内存 - 不用
+=拼接 XML 字符串——Python 字符串不可变,每次拼接都新建对象 - 不把上百万条记录先存成 list 再统一构建树——改用生成器函数 yield 每个
Element - 不依赖
minidom或ElementTree.write()一次性输出——它们强制加载完整 DOM
简单示例:拼接 10 万条 - 节点
用 XMLFile 实现稳定高速写入:
from lxml import etree
from lxml.etree import XMLFile
def gen_items(count):
for i in range(count):
elem = etree.Element('item', id=str(i))
title = etree.SubElement(elem, 'title')
title.text = f'文档 {i}'
yield elem
with XMLFile(open('big.xml', 'wb')) as xf:
xf.write_declaration(standalone=True)
root = etree.Element('root')
xf.write_start_element(root)
for item in gen_items(100000):
xf.write_element(item)
xf.write_end_element()
该方式写入 10 万条约 2 秒内完成,峰值内存低于 10 MB。










