JSON转CSV调用XML查找表出现NoneType无text属性报错如何解决
错误原因
- 数字类键的判断逻辑完全错误:
str.isdigit()仅对无小数点的纯整数字符串返回True,类似"4600.0"这类带小数点的数字字符串会返回False,导致程序错误进入alias属性查询分支,而XML中无对应alias的节点,find()方法返回None,直接访问.text属性就会触发AttributeError。 - 无查询失败兜底逻辑:只要XML中没有对应配置的键(比如示例JSON中的
"4600.2"键,XML中无对应id/alias配置),find()都会返回None,直接访问.text必然报错。 - (性能问题)每次调用查找函数都重新解析XML文件,重复IO操作严重拖慢运行效率。
- (隐藏逻辑问题)CSV写入逻辑未保证表头和数据的顺序对应,Python 3.7之前字典的键值顺序不固定,直接写
emp.values()会出现列错位。
修复方案
第一步:优化查找逻辑,提前解析XML
import xml.etree.ElementTree as ET # 全局只解析一次XML查找表,避免重复IO LOOKUP_TREE = ET.parse('columnLookup.xml').getroot().find('fields') def get_name_from_id(search_id): # 修正数字类键的判断逻辑,支持带小数点的数字字符串 is_number = False try: float(search_id) is_number = True except ValueError: pass # 按对应规则查找节点 if is_number: node = LOOKUP_TREE.find(f'field[@id="{search_id}"]') else: node = LOOKUP_TREE.find(f'field[@alias="{search_id}"]') # 查找失败兜底返回原键,避免报错 return node.text if node is not None else search_id
第二步:修正CSV写入逻辑,保证列顺序一致
def write_to_csv_file(self): import csv, json with open(self.mJSON_file_name, encoding='utf-8') as json_file: data = json.load(json_file) # 用with托管csv文件,无需手动close with open(self.mCSV_file_name, 'w', encoding='utf-8', newline='') as csv_file: csv_writer = csv.writer(csv_file) if not data: return # 固定原键顺序,避免列错位 origin_keys = list(data[0].keys()) # 生成别名表头 header = [get_name_from_id(k) for k in origin_keys] csv_writer.writerow(header) # 按原键顺序读取数据写入 for emp in data: row = [emp[k] for k in origin_keys] csv_writer.writerow(row) self.mCSV_data = csv_file
补充说明
如果要处理示例中"4600.2"这类XML中未配置的键,需要提前在XML的fields节点下补充对应的field配置,否则会直接返回原键作为表头。
内容的提问来源于stack exchange,提问作者Trey6
相关产品推荐
相关产品推荐

