Python xmltodict转JSON乱码 解决字典转JSON时的编码问题

2次阅读

根本原因是json.dumps()默认ensure_ASCII=true导致中文转义,且xml文件编码未正确指定或写入json时未设utf-8编码。需三步:确认源xml编码→用对应encoding读取→parse后dumps时设ensure_ascii=false并以utf-8写入。

Python xmltodict转JSON乱码 解决字典转JSON时的编码问题

xmltodict.parse() 返回的字典含中文但 json.dumps() 出现乱码

根本原因不是 xmltodict 本身出错,而是 json.dumps() 默认不启用中文字符转义,且未指定 ensure_ascii=False —— 它会把所有非 ASCII 字符(比如中文)强制编码uXXXX 形式,看起来像乱码,实际是 Unicode 转义序列。

  • 如果你用 print(json.dumps(data)) 看到一 u4f60u597d,这不是乱码,是 JSON 标准行为;真正要写入文件或传给前端时才需要可读中文
  • 必须显式传参 ensure_ascii=False,否则无论输入多干净,输出都是转义形式
  • 如果原始 XML 文件本身是 GBK 编码,而你没指定 encodingxmltodict.parse(),那第一步就已损坏——此时 json.dumps 再怎么设也救不回来

从文件读取 XML 时 encoding 参数漏设导致后续全乱

xmltodict.parse() 接收字符串,不自动探测编码。若 XML 文件是 GBKGB2312,直接用 open(path).read()(默认 UTF-8)读取,就会解码失败,产生 UnicodeDecodeError 或静默乱码。

  • 先确认 XML 文件真实编码:可用命令行 file -i filename.xmllinux/macos)或 VS Code 底部状态栏查看
  • 读取时务必显式指定:with open('data.xml', 'r', encoding='gbk') as f: xml_str = f.read()
  • 再传给 xmltodict.parse(xml_str);跳过这步,后面所有 JSON 操作都在错误数据上叠加
  • 如果 XML 声明里写了 <?xml version="1.0" encoding="GBK"?>xmltodict 不会自动按它解码,仍需你手动处理

json.dumps() 写入文件后打开仍是乱码

即使加了 ensure_ascii=False,写入文件时若没指定文件编码,python 默认用系统 locale(windows 常为 GBK),而编辑器(如 VS Code、Notepad++)可能按 UTF-8 解析,显示就错位。

  • 写文件必须配对指定编码:with open('out.json', 'w', encoding='utf-8') as f: f.write(json.dumps(data, ensure_ascii=False, indent=2))
  • 不要用 open(...).write(...) 两步分开,避免中间字符串隐式转换
  • 检查目标文件是否真为 UTF-8:用 file -i out.json 验证,或在编辑器里看右下角编码标识
  • 如果下游系统(如 Java 后端)要求 bom 头,需手动加 'ufeff' 前缀,但绝大多数现代 JSON 解析器不需要也不推荐

嵌套层级深、含特殊字符时 json.dumps() 报错

xmltodict 可能将 XML 注释、CDATA、属性等转为特殊结构(如 @ 开头键名、#text 键),若其中混入不可 JSON 序列化的类型(如 datetime、自定义对象),json.dumps() 直接抛 TypeError

立即学习Python免费学习笔记(深入)”;

  • 常见报错:Object of type datetime is not JSON serializable —— 检查 XML 是否含时间戳字段,被解析为 datetime 对象
  • 简单过滤:用 default 参数兜底,例如 json.dumps(data, default=str, ensure_ascii=False),把所有非标类型转成字符串
  • 更稳妥做法:先递归遍历字典,把 datetimebytes 等转成 ISO 格式字符串或 base64,而不是依赖 default=str(它会把 bytes 转成 b'xxx' 这种不可逆形式)
  • 注意:XML 属性值默认变成字符串,但某些 parser 配置可能保留原始类型,需实测验证

实际跑通的关键顺序就三步:确认源文件编码 → 用对应 encoding 读成字符串 → xmltodict.parse() 得字典 → json.dumps(..., ensure_ascii=False) + open(..., encoding='utf-8') 写入。漏掉任一环,中文都会“消失”。

text=ZqhQzanResources