CSV无法直接表达XML嵌套结构,因其是二维表格格式,缺乏父子、兄弟或重复节点概念;主流做法是用XPath定位上下文并展开重复节点为独立记录,同时区分属性与文本字段。

XML嵌套结构在CSV中天然无法直接表达
CSV 是二维表格格式,没有父子、兄弟或重复节点的概念。XML 中的 这类重复子元素,强行扁平化会导致行数膨胀或字段语义丢失——这不是工具不行,是模型不匹配。
用 XPath 提取路径 + 展开重复节点是主流做法
核心思路:把每个 视为一条独立记录,用 XPath 定位其上下文(如所属 ),再拼接字段。Python 的 xml.etree.ElementTree 或 lxml 都支持 .findall() 和 .get()。
import xml.etree.ElementTree as ET
import csv
tree = ET.parse("orders.xml")
root = tree.getroot()
with open("output.csv", "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=["order_id", "item_name", "item_price"])
writer.writeheader()
for order in root.findall("order"):
order_id = order.get("id")
for item in order.findall("item"):
row = {
"order_id": order_id,
"item_name": item.findtext("name") or "",
"item_price": item.findtext("price") or ""
}
writer.writerow(row)
- 避免用
root.iter("item")直接遍历——会丢失所属order上下文 -
findtext()比find().text更安全,空节点返回None而非报错 - 若存在多层嵌套(如
),需决定是否展开为red item_specs_color字段,还是跳过
遇到属性+文本混合时字段命名要加后缀
XML 元素既含属性又含文本(如 )时,CSV 字段必须区分来源,否则语义混淆。常见做法是加 _attr 和 _text 后缀。
- 生成字段名:
price_currency_attr和price_text - 不要合并成一个
price字段——你无法判断 29.99 是值还是 currency 值 - 如果业务上只关心文本值,就忽略属性;但得明确这个决策,不能靠“默认行为”掩盖
深层嵌套(3 层以上)建议先转 JSON 再导出
当 XML 出现 这类结构,硬编码 XPath 易出错且难维护。更稳妥的方式是先用 xmltodict 或 lxml.objectify 转成嵌套字典,再递归展平(flatten)或按需提取关键路径。
-
pip install xmltodict后,xmltodict.parse(xml_str)返回标准 Python dict - 展平时注意:重复标签(如多个
item)会被转成 list,需用for item in data['order']['item']:显式迭代 - 不要试图写通用“XML→CSV”函数——不同业务的嵌套语义差异太大,字段裁剪和层级截断点必须人工确认










