Python XML扁平化核心是递归遍历+路径拼接生成键值对,常用xml.etree.ElementTree(轻量)或lxml(支持命名空间/CData),亦可用pandas.read_xml处理表格型XML。

Python把XML扁平化,核心是把嵌套的树状结构转成一维的键值对(如字典或列表),常用方法是递归遍历+路径拼接。关键在于如何定义“扁平化”——多数场景指生成形如 {"root.child.grandchild": "value"} 的结构,或带类型/属性信息的展平结果。
用xml.etree.ElementTree递归提取(轻量、标准库)
适合结构较规则、不需保留命名空间或复杂属性的XML。思路是深度优先遍历,用点号连接路径,遇到文本内容就存入字典:
- 跳过纯空白文本和注释节点
- 对同一层级多个同名子元素,可加序号后缀(如
"items.item.0.name")避免覆盖 - 若需保留属性,可拼在路径末尾(如
"div.@class")或单独存为"div.attr.class"
示例代码片段:
import xml.etree.ElementTree as ETdef flatten_xml(element, path="", result=None): if result is None: result = {}
当前路径(去掉开头的点)
current_path = f"{path}.{element.tag}" if path else element.tag # 存文本内容(非None且非空白) if element.text and element.text.strip(): result[current_path] = element.text.strip() # 处理属性 for k, v in element.attrib.items(): result[f"{current_path}.@{k}"] = v # 递归子元素 for child in element: flatten_xml(child, current_path, result) return resulttree = ET.fromstring("
1 ") print(flatten_xml(tree))2 输出:{'root.a': '1', 'root.b.c': '2', 'root.b.c.@attr': 'x'}
用lxml增强处理(支持命名空间、XPath、更健壮)
当XML含命名空间、CDATA、混合内容或需按条件筛选时,lxml 更可靠。它提供 iter()、XPath 和 getchildren() 等灵活接口:
立即学习“Python免费学习笔记(深入)”;
- 用
etree.XPath提前获取所有含文本的叶子节点,再反推路径 - 通过
node.getparent()向上追溯,构造完整路径 - 对命名空间,注册前缀后使用
{http://ns}tag或用namespaces参数
用pandas.read_xml(适合表格型XML)
如果XML本质是二维数据(如Excel导出、RSS条目、配置列表),直接用 pandas.read_xml() 最省事。它能自动识别重复标签为行,属性转列为列:
- 指定
xpath定位记录节点(如"//item") - 用
attrs参数声明哪些属性要提升为列 - 结果是DataFrame,天然“扁平”,可直接导出CSV/Excel
例如:pd.read_xml("data.xml", xpath="//product", attrs=["id", "category"])
注意事项与边界情况
扁平化不是万能转换,需提前明确需求:
- 父子同名标签(如
)必须用索引或上下文区分,否则丢失结构- ...
- 文本与子元素混用(mixed content)时,
element.text只返回第一个文本块,后续需遍历element.itertext() - 空元素(
)或只有属性无文本的节点,需主动存空字符串或None,避免漏项










