如何在Python中不硬编码键,按动态模型从XML转字典提取数据?
动态从嵌套字典提取字段实现XML转XLSX
核心思路
从MySQL配置表中获取选中导出模型对应的字段嵌套路径,通过通用函数解析路径从xmltodict生成的嵌套字典中取值,最终组装成DataFrame导出为XLSX。
步骤实现
1. 从数据库获取模型对应的字段路径
先通过关联查询拿到目标模型(如"详细版")对应的所有字段嵌套路径,假设你的field_xml表中path字段存储的是用点分隔的路径字符串(比如nfeProc.NFe.infNFe.ide.nNF):
import pymysql def get_model_field_paths(target_model): # 替换为你的数据库连接信息 conn = pymysql.connect( host="your_db_host", user="your_db_user", password="your_db_pwd", database="your_db_name" ) cursor = conn.cursor() # 关联查询模型对应的所有字段路径 query = """ SELECT f.path FROM export_model_xml m JOIN model_field mf ON m.id = mf.model_id JOIN field_xml f ON mf.field_id = f.id WHERE m.model_name = %s """ cursor.execute(query, (target_model,)) # 提取所有路径到列表 field_paths = [row[0] for row in cursor.fetchall()] cursor.close() conn.close() return field_paths
2. 通用嵌套字典取值函数
写一个工具函数,根据路径字符串逐层遍历字典,支持数组下标(比如路径items.0.name表示取items列表中第1个元素的name值):
def get_nested_value(nested_dict, path): keys = path.split(".") current_data = nested_dict try: for key in keys: # 处理数组下标(如"0"转为整数索引) if key.isdigit(): current_data = current_data[int(key)] else: current_data = current_data[key] return current_data except (KeyError, IndexError, TypeError): # 路径不存在或类型错误时返回None,可根据业务调整为默认值 return None
3. 整合XML解析与导出流程
结合xmltodict解析XML,再批量提取字段值生成DataFrame并导出:
import xmltodict import pandas as pd def xml_to_xlsx(xml_file_path, target_model, output_xlsx_path): # 读取并解析XML为字典,根据你的XML结构调整xmltodict参数 with open(xml_file_path, "r", encoding="utf-8") as f: xml_content = f.read() # attr_prefix='' 可去除XML属性的@前缀,根据实际需求调整 xml_dict = xmltodict.parse(xml_content, attr_prefix='') # 假设XML解析后的数据条目在指定节点下,需根据你的XML结构修改 # 示例:如果是单个NFe节点,转为列表统一处理 nfe_items = xml_dict.get("nfeProc", {}).get("NFe", []) if not isinstance(nfe_items, list): nfe_items = [nfe_items] # 获取当前模型的字段路径 field_paths = get_model_field_paths(target_model) # 组装每行数据 data_rows = [] for item in nfe_items: row = {} for path in field_paths: # 用路径的最后一个节点作为列名,也可从数据库的field_xml表中读取自定义列名 column_name = path.split(".")[-1] row[column_name] = get_nested_value(item, path) data_rows.append(row) # 生成DataFrame并导出 df = pd.DataFrame(data_rows) df.to_excel(output_xlsx_path, index=False)
关键注意事项
- 路径格式统一:确保
field_xml表中存储的路径分隔符(如点.)与get_nested_value函数中的split(".")一致。 - XML解析参数:xmltodict的
attr_prefix、force_list等参数需根据你的XML实际结构调整,避免属性或列表解析异常。 - 异常处理:可根据业务需求修改
get_nested_value的异常返回值(比如返回空字符串、抛出告警等)。 - 字段列名自定义:如果需要更友好的列名,可在
field_xml表中新增field_name字段,查询时一并获取,替换代码中的column_name。
内容的提问来源于stack exchange,提问作者Lucas Marques
相关产品推荐
相关产品推荐

