XML作为半结构化数据格式,支持多层嵌套的节点和属性定义,而CSV仅能存储二维表格数据,因此将XML映射到CSV时,嵌套结构的处理是核心难点。需要先将嵌套的XML结构拆解成扁平化的字段,才能对应到CSV的列中。

XML嵌套结构的常见类型
XML的嵌套结构主要分为三类,不同类型的处理方式略有差异:
- 多层嵌套节点:父节点下包含子节点,子节点下还有更深层的节点,比如
<user>节点下包含<address>节点,<address>下又有<city>节点。 - 重复子节点:同一个父节点下存在多个同名的子节点,比如
<order>节点下有多个<item>子节点,每个<item>代表一个商品。 - 节点属性与文本内容混合:节点既包含属性,又包含文本内容,比如
<product id="1001">手机</product>,id是属性,手机是文本内容。
嵌套结构的处理思路
1. 多层嵌套节点展开
对于多层嵌套的节点,通常采用路径拼接的方式生成扁平字段名,将深层节点的内容映射到CSV的列中。比如<user><address><city>北京</city></address></user>,可以生成字段user_address_city,值为北京。
2. 重复子节点合并
如果父节点下存在多个重复子节点,有两种常见处理方式:一是将重复子节点的内容用分隔符拼接成字符串,放到同一个CSV字段中;二是将每个重复子节点展开成独立的行,父节点的其他信息重复填充。
3. 属性与文本内容分离
节点的属性和文本内容需要分别提取,属性可以拼接字段名,比如<product id="1001">可以生成product_id字段,节点的文本内容可以生成product_text字段,避免数据混淆。
Python实现示例
下面使用Python的xml.etree.ElementTree模块解析XML,结合csv模块完成嵌套XML到CSV的转换,示例处理的XML包含多层嵌套和重复子节点:
import xml.etree.ElementTree as ET
import csv
# 示例XML内容
xml_content = """<?xml version="1.0" encoding="UTF-8"?>
<users>
<user id="1">
<name>张三</name>
<age>25</age>
<address>
<province>北京</province>
<city>北京</city>
<district>海淀区</district>
</address>
<orders>
<order>订单1001</order>
<order>订单1002</order>
</orders>
</user>
<user id="2">
<name>李四</name>
<age>30</age>
<address>
<province>上海</province>
<city>上海</city>
<district>浦东新区</district>
</address>
<orders>
<order>订单2001</order>
</orders>
</user>
</users>"""
# 解析XML
root = ET.fromstring(xml_content)
# 存储所有行的数据
rows = []
# CSV表头
headers = ["user_id", "name", "age", "address_province", "address_city", "address_district", "orders"]
for user in root.findall("user"):
# 提取用户属性
user_id = user.get("id")
# 提取子节点文本
name = user.find("name").text if user.find("name") is not None else ""
age = user.find("age").text if user.find("age") is not None else ""
# 提取嵌套的address节点内容
address = user.find("address")
province = address.find("province").text if address is not None and address.find("province") is not None else ""
city = address.find("city").text if address is not None and address.find("city") is not None else ""
district = address.find("district").text if address is not None and address.find("district") is not None else ""
# 提取重复order节点内容,用分号拼接
orders = user.find("orders")
order_list = []
if orders is not None:
for order in orders.findall("order"):
order_list.append(order.text)
orders_str = ";".join(order_list)
# 组装行数据
row = [user_id, name, age, province, city, district, orders_str]
rows.append(row)
# 写入CSV文件
with open("output.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(headers)
writer.writerows(rows)
print("XML转CSV完成,输出文件为output.csv")
注意事项
处理嵌套XML映射时,需要根据实际业务需求选择重复子节点的处理方式,如果重复子节点的每个实例都需要独立统计,建议展开成多行;如果只是需要保留所有内容,用分隔符拼接更合适。另外,转换前需要明确XML的结构,避免遗漏深层嵌套的节点数据,导致CSV内容不完整。
XMLCSVXML_to_CSV嵌套结构处理修改时间:2026-07-19 16:21:26