使用CSV文件存储的值更新Python lxml etree子元素属性的方法
解决方案
你用csv.DictReader读取的每一行数据本身就是以CSV表头为键的字典,直接通过字段名就能取出对应值替换写死的Test。按你按Gruppering分组的逻辑,同一分组内Personnummer是统一的,先从分组首行取该值,再遍历分组内所有行生成对应Anstallning节点和子节点即可,修改后的完整代码如下:
from lxml import etree from itertools import groupby import csv with open(r'\\ora-2.ug.test.se\utdata\Diverse filer\Öppna H3\Arbetsdokument\TestCSV.csv', encoding='utf-8') as data_file: reader = csv.DictReader(data_file) group_key = lambda x: x['Gruppering'] data = sorted(list(reader), key=group_key) root = etree.Element('root') for group_val, rows in groupby(data, key=group_key): # 转成列表方便取首行和遍历 row_list = list(rows) # 取分组内统一的Personnummer person_num = row_list[0]['Personnummer'] # 生成Arbetstagare节点,直接传属性值 arbetstagare = etree.SubElement(root, 'Arbetstagare', Personnummer=person_num) # 遍历分组内每一行生成对应Anstallning节点 for row in row_list: anstallning = etree.SubElement(arbetstagare, 'Anstallning', Anstallningsnummer=row['Anstallningsnummer']) # 生成Period节点和下属字段 period = etree.SubElement(anstallning, 'Period') for field in ['From', 'Tom', 'Avtalstillhorighet', 'Pensionsalder', 'Anstallningstyp', 'Avslutsorsak']: sub_ele = etree.SubElement(period, field) sub_ele.text = row[field] # 可选:格式化输出XML验证结果 print(etree.tostring(root, pretty_print=True, encoding='unicode'))
补充说明
你之前猜测的set方法或者直接修改attrib属性也可以实现,和创建节点时直接传属性参数效果一致,比如以下两种写法和上面的属性赋值效果完全相同:
- 方法1:
arbetstagare.set('Personnummer', person_num) - 方法2:
arbetstagare.attrib['Personnummer'] = person_num
代码加了encoding='utf-8'避免读取含特殊字符的CSV时出现乱码,你可以根据实际CSV的编码调整参数。
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

