
本文介绍如何利用 Python 的 csv 和 xml.etree.ElementTree 模块,将多行客户-卡片映射的 CSV 数据正确聚合生成符合业务逻辑的嵌套 XML 文件,重点解决元素层级错位与重复节点遗漏问题。
本文介绍如何利用 python 的 `csv` 和 `xml.etree.elementtree` 模块,将多行客户-卡片映射的 csv 数据正确聚合生成符合业务逻辑的嵌套 xml 文件,重点解决元素层级错位与重复节点遗漏问题。
在实际数据集成场景中,常需将扁平化的 CSV 表格(如客户 ID 与多张卡号的一对多关系)转换为具有明确层级结构的 XML 格式(例如每个
以下是修复后的完整、可直接运行的解决方案:
import csv
import xml.etree.ElementTree as ET
from collections import defaultdict
def generate_xml_from_csv(input_file: str, output_file: str) -> None:
"""
将 CSV 文件中的 CustID-CardNo 映射关系转换为嵌套 XML。
每个唯一 CustID 对应一个 <card> 元素,其下包含 <custholderheader> 和多个 <cardline>。
"""
# 步骤1:读取并分组数据
cards_per_custid = defaultdict(list)
with open(input_file, 'r', newline='', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
cust_id = row["CustID"].strip()
card_no = row["CardNo"].strip()
if cust_id and card_no: # 过滤空行/无效数据
cards_per_custid[cust_id].append(card_no)
# 步骤2:构建 XML 树
root = ET.Element(
"ReceivableAccounting",
attrib={"xmlns": "http://www.sample.com/testing"}
)
# 按 CustID 字典序排序,确保输出稳定
for cust_id in sorted(cards_per_custid.keys()):
cards = cards_per_custid[cust_id]
# 创建 Card 元素(每个客户一个)
card_el = ET.SubElement(root, "Card")
# 添加 CustHolderHeader 子元素
header = ET.SubElement(card_el, "CustHolderHeader")
ET.SubElement(header, "CustID").text = cust_id
# 为该客户的每张卡添加 CardLine
for card_no in cards:
line = ET.SubElement(card_el, "CardLine")
ET.SubElement(line, "CardDetail").text = card_no
# 步骤3:格式化并写入文件
tree = ET.ElementTree(root)
ET.indent(tree, space=" ") # Python 3.9+ 支持;旧版本可省略或使用第三方库
tree.write(
output_file,
encoding="utf-8",
xml_declaration=True # 确保生成 <?xml version="1.0" encoding="UTF-8"?>
)
print(f"✅ XML 文件已成功生成:{output_file}")
# 使用示例
if __name__ == "__main__":
input_csv = "Input.csv"
output_xml = "output.xml"
# 确保输入文件存在(此处可替换为真实路径)
generate_xml_from_csv(input_csv, output_xml)</cardline></custholderheader></card>
关键修正点说明:
- ✅ 层级逻辑修复:for card_no in cards: 循环严格嵌套在 for cust_id in sorted(...) 内部,确保每张卡都归属于其对应客户的
元素下; - ✅ XML 声明与编码:通过 xml_declaration=True 自动添加 头;
- ✅ 健壮性增强:增加 strip() 清理首尾空格、空值校验,避免生成无效 XML 文本;
- ✅ 可维护性提升:函数化封装、类型提示、详细注释,便于复用与调试。
注意事项:
- 若使用 Python
- xmlns 属性在 ElementTree 中仅作字符串处理,不触发命名空间解析;若需严格命名空间支持(如带前缀),应使用 lxml 库;
- 生产环境建议添加异常处理(如 FileNotFoundError, csv.Error)并验证输入字段完整性。
此方案简洁、高效且符合 XML 最佳实践,可直接集成至 ETL 流程或自动化脚本中。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











