Python多格式链式转换中JSON转XML写入文件报错如何解决?
问题根因
- 首次pandas转换报错
AttributeError: 'ElementTree' object has no attribute 'tag':xml.etree.ElementTree.tostring()方法接收的参数是Element节点对象,你传入了封装好的ElementTree对象,导致属性匹配失败;同时tostring()默认返回bytes类型,直接用文本模式写入文件会报错。 - 方案1转换后报
KeyError: 'Title':该方案生成的JSON结构是{动漫标题: {属性字典}}的嵌套对象,根层级没有Title键,Title是子对象的属性。 - 方案2转换后报
TypeError: list indices must be integers or slices, not str:该方案生成的JSON是行对象数组,根层级是列表,不能用字符串作为索引取值。
可行解决方案
我们采用「方案2生成数组型JSON + 适配数组的XML转换逻辑」的组合方案,兼容性更强,也符合多条目数据集的存储习惯。
第一步:CSV转JSON(直接使用方案2代码即可,仅做微小兼容调整)
import csv import json import time def csv_to_json(csvFilePath, jsonFilePath): jsonArray = [] with open(csvFilePath, encoding='utf-8') as csvf: csvReader = csv.DictReader(csvf) for row in csvReader: jsonArray.append(row) with open(jsonFilePath, 'w', encoding='utf-8') as jsonf: # 新增ensure_ascii=False避免非ASCII字符乱码 jsonString = json.dumps(jsonArray, indent=4, ensure_ascii=False) jsonf.write(jsonString) csvFilePath = r'dataanime.csv' jsonFilePath = r'g_d_anime.json' start = time.perf_counter() csv_to_json(csvFilePath, jsonFilePath) finish = time.perf_counter() print(f"转换完成,耗时{finish - start:0.4f}秒")
第二步:修改JSON转XML代码,适配数组结构
import json as j import xml.etree.ElementTree as et # 加载JSON文件 with open("g_d_anime.json", encoding='utf-8') as json_file: anime_list = j.load(json_file) # 创建根节点 root = et.Element("AnimeList") # 遍历所有动漫条目,逐个生成Work子节点 for anime in anime_list: work_node = et.SubElement(root, "Work") # 逐个添加属性,用get方法避免空值/字段缺失报错 et.SubElement(work_node,"Title").text = anime.get("Title", "") et.SubElement(work_node,"Type").text = anime.get("Type", "") et.SubElement(work_node,"Episodes").text = anime.get("Episodes", "") et.SubElement(work_node,"Status").text = anime.get("Status", "") et.SubElement(work_node,"Start airing").text = anime.get("Start airing", "") et.SubElement(work_node,"End airing").text = anime.get("End airing", "") et.SubElement(work_node,"Starting season").text = anime.get("Starting season", "") et.SubElement(work_node,"Broadcast time").text = anime.get("Broadcast time", "") et.SubElement(work_node,"Producers").text = anime.get("Producers", "") et.SubElement(work_node,"Licensors").text = anime.get("Licensors", "") et.SubElement(work_node,"Studios").text = anime.get("Studios", "") et.SubElement(work_node,"Sources").text = anime.get("Sources", "") et.SubElement(work_node,"Genres").text = anime.get("Genres", "") et.SubElement(work_node,"Duration").text = anime.get("Duration", "") et.SubElement(work_node,"Rating").text = anime.get("Rating", "") et.SubElement(work_node,"Score").text = anime.get("Score", "") et.SubElement(work_node,"Scored by").text = anime.get("Scored by", "") et.SubElement(work_node,"Members").text = anime.get("Members", "") et.SubElement(work_node,"Favorites").text = anime.get("Favorites", "") et.SubElement(work_node,"Description").text = anime.get("Description", "") # 生成XML字符串,直接传根Element对象而非ElementTree对象,指定编码 xml_str = et.tostring(root, encoding='utf-8', method='xml') # 用二进制模式写入文件,避免编码转换问题 with open("json_to_xml.xml", 'wb') as outfile: # 写入标准XML声明 outfile.write(b'<?xml version="1.0" encoding="UTF-8"?>\n') outfile.write(xml_str)
修复说明
- 遍历JSON数组的每一个条目生成对应的XML节点,适配多数据的结构
- 调用
tostring()时传入根Element对象而非ElementTree对象,解决属性报错 - 用
dict.get()方法取值,避免字段缺失导致的KeyError - 采用二进制模式写入文件,直接输出bytes类型的XML内容,避免编码转换错误
内容的提问来源于stack exchange,提问作者SassyG
相关产品推荐
相关产品推荐

