
XML 是一种广泛使用的结构化数据存储格式,但对于数据分析或 Excel 等表格工具而言并不够友好。将 XML 转换为 CSV 可以将数据整理成更简单的二维表格格式,这种格式兼容电子表格和数据分析库。通过将 XML 转换为 CSV,你可以轻松地将数据导入 Excel、执行计算,或将其作为输入数据提供给 Pandas 等 Python 数据分析工具。
这种方法还有助于将复杂的层级数据标准化为更易于阅读、处理和共享的格式。在本教程中,我们将探讨如何使用 Spire.XLS for Python 高效地将 XML 文件转换为 CSV。
- 安装 Spire.XLS for Python
- 理解 XML 数据结构
- 如何提取并转换 XML 数据
- 基础示例:使用 Python 将 XML 转换为 CSV
- 高级技巧
- 故障排除与解决方案
- 总结
- 常见问题解答
安装 Spire.XLS for Python
开始之前,需要先安装 Spire.XLS。该库已发布到 PyPI,可直接使用 pip 安装:
pip install spire.xls
安装完成后,导入所需类:
from spire.xls import *
from spire.xls.common import *
Spire.XLS 提供了 Workbook 和 Worksheet 对象,用于管理类似 Excel 的工作簿和工作表。后续我们将利用它们创建 CSV 文件并写入 XML 数据。
理解 XML 数据结构
XML 文件采用树状层级结构组织数据,其中元素(节点)由标签包裹。每个元素可以包含文本内容、属性以及其他子元素。
例如下面的 Books.xml:
<catalog>
<book isbn="9787020002207">
<title>红楼梦</title>
<author>曹雪芹</author>
<year>1791</year>
<genre>古典文学</genre>
<price>68.00</price>
<reviews>
<review>中国古典文学的巅峰之作</review>
</reviews>
</book>
<book isbn="9787506365437">
<title>三体</title>
<author>刘慈欣</author>
<year>2008</year>
<genre>科幻</genre>
</book>
</catalog>
- 根节点(Root Node):<catalog> 是整个 XML 的顶层容器。
- 子节点(Child Nodes):每个 <book> 都是 <catalog> 的子节点。
- 元素(Elements):<title>、<author> 和 <genre> 是书籍信息元素。
- 属性(Attributes):<book isbn="..."> 中的 isbn 是附加在 book 元素上的属性。
- 嵌套元素(Nested Elements):<reviews> 中包含多个 <review> 子节点。
XML 转 CSV 面临的挑战:
- 层级结构与表格结构不一致:XML 支持嵌套,而 CSV 是扁平化格式。
- 属性与元素并存:数据可能存储在属性中(如 isbn),也可能存储在标签中(如 title)。
- 可选字段:并非所有 <book> 节点都包含相同的元素,这可能导致 CSV 中出现缺失值。
因此,一个可靠的转换程序必须能够将 XML 的层级结构映射到 CSV 的表格结构中。
如何提取并转换 XML 数据
要在 Python 中加载并解析 XML 文件,可以使用 内置的 xml.etree.ElementTree 库。该库可以用于解析 XML 文件。
示例:
import xml.etree.ElementTree as ET
# 加载 XML 文件
tree = ET.parse("Books.xml")
root = tree.getroot()
# 遍历书籍节点
for book in root.findall("book"):
title = book.findtext("title", "")
author = book.findtext("author", "")
isbn = book.attrib.get("isbn", "")
完成数据提取后,就可以利用 Spire.XLS for Python 创建工作簿并导出 CSV 文件。
在 Python 中将 XML 转换为 CSV 的基本流程:
- 使用 xml.etree.ElementTree 解析 XML。
- 创建 Workbook 对象。
- 使用 Workbook.Worksheets.Add() 创建工作表。
- 使用 Worksheet.SetValue() 将提取的 XML 数据写入工作表。
- 使用 Worksheet.SaveToFile() 导出 CSV。
基础示例:使用 Python 将 XML 转换为 CSV
让我们从一个基础的 XML 到 CSV 转换开始。下面的示例会自动读取第一个 <book> 元素生成表头,然后将所有子节点导出到 CSV 中。
from spire.xls import *
from spire.xls.common import *
import xml.etree.ElementTree as ET
# 创建 Workbook
workbook = Workbook()
# 删除默认工作表
workbook.Worksheets.Clear()
# 添加工作表
worksheet = workbook.Worksheets.Add("Books")
# 加载 XML 文件
xml_tree = ET.parse("C:\\Users\\Administrator\\Desktop\\Books.xml")
xml_root = xml_tree.getroot()
# 获取第一个 book 节点
first_book = xml_root.find("book")
# 提取表头
header = list(first_book.iter())[1:]
# 定义英文和中文标签的映射关系
label_mapping = {
"title": "书名",
"author": "作者",
"year": "年份",
"genre": "类型",
}
# 写入表头
for col_index, header_node in enumerate(header, start=1):
en_tag = header_node.tag
cn_tag = label_mapping.get(en_tag, en_tag)
worksheet.SetValue(1, col_index, cn_tag)
# 写入数据
row_index = 2
for book in xml_root.iter("book"):
for col_index, data_node in enumerate(list(book.iter())[1:], start=1):
worksheet.SetValue(row_index, col_index, data_node.text)
row_index += 1
# 保存 CSV
worksheet.SaveToFile("output/XmlToCsv.csv", ",", Encoding.get_UTF8())
# 释放资源
workbook.Dispose()
该脚本适用于结构简单的 XML 文件,可自动生成表头(书名、作者、年份、类型),并写入对应数据。
输出:

你可能还会感兴趣: 在 Python 中将 XML 转换为 Excel 和 PDF
高级技巧
基础脚本在许多情况下都适用,但 XML 往往并非如此简单。下面介绍一些处理实际场景的高级技巧。
仅导出指定元素
有时 XML 中包含大量数据,但你只需要部分字段。
例如,仅导出书名和作者:
from spire.xls import *
from spire.xls.common import *
import xml.etree.ElementTree as ET
# 创建 Workbook 对象
workbook = Workbook()
# 移除默认工作表
workbook.Worksheets.Clear()
# 添加工作表并命名
worksheet = workbook.Worksheets.Add("Books")
# 加载 XML 文件
xml_tree = ET.parse(r"C:\Users\Administrator\Desktop\Books.xml")
xml_root = xml_tree.getroot()
# 定义想要导出的元素
selected_elements = ["title", "author"]
# 定义英文和中文标签的映射关系
label_mapping = {
"title": "书名",
"author": "作者",
}
# 写入表头
for col_index, tag in enumerate(selected_elements, start=1):
cn_tag = label_mapping.get(tag, tag)
worksheet.SetValue(1, col_index, cn_tag)
# 写入数据
row_index = 2
for book in xml_root.iter("book"):
for col_index, tag in enumerate(selected_elements, start=1):
# 使用 findtext 安全地处理缺失值
worksheet.SetValue(row_index, col_index, book.findtext(tag, ""))
row_index += 1
# 保存 CSV
worksheet.SaveToFile("output/XmlToCsv_Selected.csv", ",", Encoding.get_UTF8())
# 释放资源
workbook.Dispose()
这样导出的 CSV 仅包含所需列。
输出:

将 XML 属性导出到 CSV
如果重要数据存储在属性中(例如 ISBN),也可以轻松导出。
from spire.xls import *
from spire.xls.common import *
import xml.etree.ElementTree as ET
# 创建 Workbook 对象
workbook = Workbook()
# 移除默认工作表
workbook.Worksheets.Clear()
# 添加工作表并命名
worksheet = workbook.Worksheets.Add("Books")
# 加载 XML 文件
xml_tree = ET.parse(r"C:\Users\Administrator\Desktop\Books.xml")
# 获取 XML 树的根元素
xml_root = xml_tree.getroot()
# 获取第一个 book 元素
first_book = xml_root.find("book")
# 提取表头信息(子节点)
header = list(first_book.iter())[1:]
# 定义英文和中文标签的映射关系
label_mapping = {
"isbn": "ISBN编号",
"title": "书名",
"author": "作者",
"year": "年份",
"genre": "类型",
}
# 将表头写入 Excel
cn_isbn = label_mapping.get("isbn", "isbn")
worksheet.SetValue(1, 1, cn_isbn) # <-- 首先添加 ISBN 列
for col_index, header_node in enumerate(header, start=2): # 现在从第 2 列开始
en_tag = header_node.tag
cn_tag = label_mapping.get(en_tag, en_tag)
worksheet.SetValue(1, col_index, cn_tag)
# 写入数据
row_index = 2
for book in xml_root.iter("book"):
# 将 isbn 作为文本写入
isbn_value = book.attrib.get("isbn", "")
worksheet.Range[row_index, 1].Text = isbn_value
# 然后写入其他字段
for col_index, data_node in enumerate(list(book.iter())[1:], start=2):
value = data_node.text
worksheet.SetValue(row_index, col_index, value)
row_index += 1
# 将整个 ISBN 列格式化为文本,以防止出现科学记数法
last_row = row_index - 1
isbn_range = f"A2:A{last_row}"
worksheet.Range[isbn_range].NumberFormat = "@"
# 保存 CSV
worksheet.SaveToFile("output/XmlToCsv_WithAttributes.csv", ",", Encoding.get_UTF8())
# 释放资源
workbook.Dispose()
这里显式地创建了一个 ISBN 列,从每个 <book> 的属性中提取它,并将其格式化为文本,以防止 Excel 以科学记数法显示它。
输出:

处理嵌套的 XML 结构
假设 XML 如下:
<catalog>
<book>
<title>活着</title>
<author>余华</author>
<reviews>
<review>一部震撼人心的作品</review>
<review>读了好几遍仍然感动</review>
<review>让人重新思考生命的意义</review>
</reviews>
</book>
</catalog>
CSV 无法直接表示多层嵌套结构,因此可以将多个 <review> 条目合并到单个 CSV 列中:
from spire.xls import *
from spire.xls.common import *
import xml.etree.ElementTree as ET
# 创建 Workbook 对象
workbook = Workbook()
# 移除默认工作表
workbook.Worksheets.Clear()
# 添加工作表并命名
worksheet = workbook.Worksheets.Add("Books")
# 加载 XML 文件
xml_tree = ET.parse(r"C:\Users\Administrator\Desktop\Nested.xml")
xml_root = xml_tree.getroot()
# 获取第一个 <book> 元素
first_book = xml_root.find("book")
# 收集表头(自动检测)
header = []
for child in first_book:
if child.tag == "reviews":
header.append("reviews") # 将嵌套的 <review> 合并到一个列中
else:
header.append(child.tag)
# 定义英文和中文标签的映射关系
label_mapping = {
"title": "书名",
"author": "作者",
"year": "年份",
"genre": "类型",
"price": "价格",
"reviews": "评论",
}
# 写入表头行
for col_index, header_text in enumerate(header, start=1):
cn_header = label_mapping.get(header_text, header_text)
worksheet.SetValue(1, col_index, cn_header)
# 写入数据行
row_index = 2
for book in xml_root.iter("book"):
col_index = 1
for child in book:
if child.tag == "reviews":
# 将所有 <review> 的文本合并到一个单元格中
reviews = [r.text for r in child.findall("review") if r.text]
worksheet.SetValue(row_index, col_index, "; ".join(reviews))
else:
worksheet.SetValue(row_index, col_index, child.text if child.text else "")
col_index += 1
row_index += 1
# 保存 CSV
worksheet.SaveToFile("output/XmlToCsv_WithReviews.csv", ",", Encoding.get_UTF8())
# 释放资源
workbook.Dispose()
输出:

Spire.XLS 不仅支持将数据从标准 XML 文件导入 Excel 或 CSV,还允许将 OpenXML(Microsoft 的基于 XML 的文件格式)转换为 Excel。如果你感兴趣,可以查看这篇教程:如何在 Python 中将 Excel 转换为 OpenXML 以及将 OpenXML 转换为 Excel。
故障排除与解决方案
即使脚本结构良好,在将 XML 转换为 CSV 时也可能遇到一些常见问题:
1. Excel 显示科学计数法
- 问题:长数字字符串(如 ISBN)可能会显示为:9.78045E+12,而非完整数字。
- 解决方案:在保存前将该列格式化为文本,例如:
worksheet.Range["A2:A{last_row}"].NumberFormat = "@"
2. 缺失字段导致报错
- 问题:部分 <book> 元素可能缺少可选字段(如 <genre>)。直接访问 .text 可能导致错误。
- 解决方案:使用 findtext(tag, "") 安全地提供一个默认的空字符串。
3. 表头不完整
- 问题:如果仅根据第一个 <book> 生成表头,后续出现的新字段会被遗漏。
- 解决方案:在写入数据之前,扫描多个元素(或整个数据集),构建一个完整的表头列表。
4. 编码问题
- 问题:特殊字符(如重音符号或其他符号)在 CSV 中可能无法正确显示。
- 解决方案:始终使用 UTF-8 编码保存:
worksheet.SaveToFile("output.csv",",", Encoding.get_UTF8())
总结
在 Python 中将 XML 转换为 CSV 并不复杂。借助 Spire.XLS for Python,你可以自动完成大部分过程,包括表头生成、处理属性以及展平嵌套节点。无论是简单 XML、复杂层级结构,还是包含大量属性的数据集,都可以通过上述方法轻松转换为便于分析的 CSV 格式。
常见问题解答
问题1:可以直接导出为 Excel(.xlsx)吗?
答:可以。只需使用 workbook.SaveToFile("output.xlsx", ExcelVersion.Version2016) 即可。
问题2:如何处理超大 XML 文件?
答:使用 Python 的 xml.etree.ElementTree 中的 iterparse() 来流式处理大文件,避免一次性加载到内存中。
问题3:如果部分 <book> 包含额外标签怎么办?
答:可以在生成表头前扫描所有 <book> 节点,动态收集所有唯一标签。
问题4:能否自定义 CSV 分隔符?
答:可以。在调用 SaveToFile() 时,替换分隔符参数即可:
worksheet.SaveToFile("output.csv", ";", Encoding.get_UTF8())
问题5:如何导出嵌套结构(如多个 <review>\)?
答:通过合并值将它们展平到单个单元格。例如:
reviews = [r.text for r in book.find("reviews").findall("review")]
worksheet.SetValue(row_index, col_index, "; ".join(reviews))
获取免费许可证
如果希望在没有评估版限制的情况下体验 Spire.XLS for Python 的全部功能,可以申请免费的 30 天试用许可证。







