使用PETL解析异构XML合并时明细字段拆分问题求助
解决方案
问题根因
PETL的fromxml方法读取XML节点时,若同一个父节点下存在多个同名子节点,会自动将多个值打包为元组存入单一行,不会自动拆分。你需要在关联表之前,先对存储Details数据的table3做行拆分处理,保证DetailOne和DetailTwo一一对应拆分为独立行。
调整后完整代码
import petl as etl import os from lxml import etree # 统一获取xml文件夹路径,避免重复拼接 xml_dir = os.path.join(os.getcwd(), 'xmlfiles') for filename in os.listdir(xml_dir): if not filename.endswith('.xml'): continue file_path = os.path.join(xml_dir, filename) # 获取Info子节点数据 table1 = etl.fromxml(file_path, 'Info', { 'Name': 'Name', 'Date': 'Date' }) # 获取App子节点数据 table2 = etl.fromxml(file_path, 'App', { 'Description': 'Description', 'Type': 'Type' }) # 获取App下Details节点数据 table3 = etl.fromxml(file_path, 'App/Details', { 'DetailOne': 'DetailOne', 'DetailTwo': 'DetailTwo' }) # 新增拆分逻辑:将元组值拆分为独立行 table3 = etl.rowmapmany( table3, ['DetailOne', 'DetailTwo'], lambda row: [ (d1, d2) for d1, d2 in zip( row.DetailOne if isinstance(row.DetailOne, (tuple, list)) else [row.DetailOne], row.DetailTwo if isinstance(row.DetailTwo, (tuple, list)) else [row.DetailTwo] ) ] ) # 关联三张表 c = etl.crossjoin(table1, table2, table3) # 新增来源文件名字段 result = etl.addfield(c, 'FileName', filename) print('结果:\n', result)
核心修改说明
- 用
os.path.join拼接路径,避免不同操作系统路径分隔符兼容问题 - 新增
rowmapmany处理逻辑:针对每一行Details数据,判断DetailOne/DetailTwo是否为元组/列表类型,如果是则按顺序配对拆分为多行,单个值则直接保留原行,保证字段一一对应。
内容的提问来源于stack exchange,提问作者variable89
相关产品推荐
相关产品推荐

