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

Python基于etree将CSV按双字段分组生成嵌套XML的实现问题

问题修复方案

完整修改后代码

from lxml import etree
from itertools import groupby
import csv

# 注意文件名要加引号,否则会报语法错误
with open('Leverans_python.csv', encoding='utf-8') as data_file:
    reader = csv.DictReader(data_file)
    # 先按Personnummer排序,再按Anstallningsnummer排序,保证两级groupby正常工作
    data = sorted(list(reader), key=lambda x: (x['Personnummer'], x['Anstallningsnummer']))
    root = etree.Element('Arbetstagarlista')
    
    # 第一级分组:按Personnummer
    for person_id, person_group in groupby(data, key=lambda x: x['Personnummer']):
        # 创建Arbetstagare节点,添加Personnummer属性,解决带属性节点生成的问题
        arbetstagare = etree.SubElement(root, 'Arbetstagare', attrib={'Personnummer': person_id})
        # 把当前员工的所有记录转成列表,用于第二级分组
        person_records = list(person_group)
        
        # 第二级分组:按Anstallningsnummer,解决多层嵌套分组的问题
        for anstallning_id, anstallning_group in groupby(person_records, key=lambda x: x['Anstallningsnummer']):
            # 创建Anstallning节点,添加Anstallningsnummer属性
            anstallning = etree.SubElement(arbetstagare, 'Anstallning', attrib={'Anstallningsnummer': anstallning_id})
            # 遍历当前雇佣编号下的所有记录,每个记录对应一个Period节点
            for entry in anstallning_group:
                period = etree.SubElement(anstallning, 'Period')
                # 批量添加子节点,避免重复代码
                for field in ['From', 'Tom', 'Avtalstillhorighet', 'Pensionsalder', 'Anstallningstyp', 'Avslutsorsak']:
                    field_node = etree.SubElement(period, field)
                    field_node.text = entry[field]

# 输出格式化XML
with open('my_data.xml', 'wb') as out_file:
    out_file.write(etree.tostring(root, pretty_print=True, encoding='utf-8'))

修复逻辑说明

  • 两级分组逻辑修复
    你原来的代码只做了第一级按Personnummer的分组,并且在循环外层就提前创建了Anstallningsnummer和Period节点,导致同一个员工的所有雇佣记录都塞到了同一个节点下。修改后新增了第二级按Anstallningsnummer的分组,每次分组后才创建对应的Anstallning节点和Period节点,保证每个雇佣编号对应独立的节点结构。
    注意groupby要求分组字段是连续有序的,所以排序的时候要同时按Personnummer和Anstallningsnummer两个字段排序,否则会出现同一个值被拆成多个分组的问题。

  • 带属性节点生成方法
    使用etree.SubElement创建节点时,传入attrib参数即可给节点添加属性,你需要的<Arbetstagare Personnummer="xxx">结构,只需要把节点名设为Arbetstagare,再给attrib字典传入Personnummer对应的取值即可,不需要把节点名设为Personnummer。

内容的提问来源于stack exchange,提问作者Martin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 09:30:00