You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 16:36:03