Pandas不原生支持XML导出,截至2.2版本无to_xml()方法;推荐用to_dict()结合xml.etree.ElementTree手动构造,需处理NaN、中文编码、非法列名等问题,并避免使用非主流第三方包。

XML导出不是Pandas原生支持的功能
Pandas没有内置的to_xml()方法(截至2.2版本),直接调用df.to_xml()会抛出AttributeError。这不是你代码写错了,是功能确实没实装——官方GitHub上长期有相关PR和讨论,但尚未合并进主线。
用to_dict() + xml.etree.ElementTree手动构造最稳妥
这是生产环境推荐做法:可控、无额外依赖、兼容所有Pandas版本。核心思路是把DataFrame转为记录列表,逐条生成Element节点,再统一包装根元素。
常见错误包括:NaN导致TypeError、中文字符编码失败、列名含空格或特殊字符引发XML格式错误。
- 先用
df.fillna("")或df.astype(str)统一字段类型,避免None/NaN传入ElementTree - 根节点名建议显式指定(如
"data"),不要硬编码为"root"——业务系统常依赖特定根名 - 列名自动转为XML标签名时,需替换非法字符:空格→
"_","-"→"_",开头数字加前缀(如"col_123")
import xml.etree.ElementTree as ET import pandas as pddef df_to_xml(df, root_name="data", row_name="record"): root = ET.Element(rootname) for , row in df.iterrows(): record = ET.SubElement(root, row_name) for col_name, val in row.items():
清洗列名:只保留字母、数字、下划线,且不能以数字开头
safe_tag = "".join(c if c.isalnum() else "_" for c in str(col_name)) if safe_tag and safe_tag[0].isdigit(): safe_tag = "col_" + safe_tag # 值转字符串并处理None text = "" if pd.isna(val) else str(val) ET.SubElement(record, safe_tag).text = text return ET.tostring(root, encoding="unicode", method="xml")示例
df = pd.DataFrame([{"user id": 101, "full-name": "Alice", "score": 95.5}]) xml_str = df_to_xml(df, root_name="users") print(xml_str)
第三方库
lxml能简化但引入新依赖如果你已用
lxml处理HTML/XML,可用其etree替代标准库,性能略好,且对命名空间、CDATA等支持更全。但注意:lxml需单独安装(pip install lxml),Windows用户可能遇到编译问题。立即学习“Python免费学习笔记(深入)”;
-
lxml.etree的tostring()默认不换行,加pretty_print=True才可读 - 若需声明XML版本和编码(如
),必须用xml_declaration=True - 避免混用
xml.etree.ElementTree和lxml.etree——对象不兼容,会报TypeError: expected ElementTree instance
别碰pandas-xml这类非主流包
PyPI上有几个叫pandas-xml或dfxml的包,下载量低、更新停滞、文档缺失。实测发现它们对多级索引、时序列、嵌套字典支持极差,且部分版本会静默丢数据(比如把datetime64转成时间戳整数后截断毫秒)。小脚本试试无妨,线上流程请绕开。
真正容易被忽略的是:XML规范要求属性值必须加引号、标签名区分大小写、空元素要闭合(而非)。手动用ElementTree时这些由底层保障;自己拼字符串则大概率出错——宁可多写几行,别省那点代码量。










