You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XML解析时如何传入两种编码类型作为参数实现统一解析

问题根因

当前代码中ET.tostring(..., encoding='utf-8/UTF-16', ...)写法错误,encoding参数仅支持传入单个合法编码字符串,斜杠拼接多编码的写法会直接触发编码识别异常。
xml.etree.ElementTree的parse方法本身遵循XML标准规范,会自动读取XML文件头部<?xml version="1.0" encoding="xxx"?>的编码声明,原生支持自动识别UTF-8、UTF-16两种编码的输入文件,无需提前硬编码指定输入编码。

正确实现

最简适配方案(覆盖99%常规场景)

统一将解析后的XML结构输出为单一编码(推荐兼容性最好的UTF-8)交给xmltodict处理即可,无论输入文件是UTF-8还是UTF-16都能正常适配:

import xml.etree.ElementTree as ET
import xmltodict

def parse_xml(xml_file_path):
    # 自动识别输入文件编码,兼容UTF-8/UTF-16
    tree = ET.parse(xml_file_path)
    xml_root = tree.getroot()
    # 统一输出为UTF-8编码,禁止传入多编码拼接值
    xml_bytes = ET.tostring(xml_root, encoding='utf-8', method='xml')
    # 转换为字典返回
    return dict(xmltodict.parse(xml_bytes))

兜底兼容方案(应对无编码声明的异常XML)

如果遇到部分缺失头部编码声明、自动识别失败的XML文件,可以通过判断文件BOM头手动识别编码:UTF-16编码的文件开头固定带0xff 0xfe或0xfe 0xff的BOM标识,无BOM的XML默认按UTF-8处理:

import xml.etree.ElementTree as ET
import xmltodict

def parse_xml(xml_file_path):
    # 读取二进制内容做编码检测
    with open(xml_file_path, 'rb') as f:
        raw_content = f.read()
    # 根据BOM判断编码
    if raw_content.startswith(b'\xff\xfe') or raw_content.startswith(b'\xfe\xff'):
        input_encoding = 'utf-16'
    else:
        input_encoding = 'utf-8'
    # 按检测到的编码解析内容
    xml_root = ET.fromstring(raw_content.decode(input_encoding))
    # 统一转UTF-8后做字典转换
    xml_bytes = ET.tostring(xml_root, encoding='utf-8', method='xml')
    return dict(xmltodict.parse(xml_bytes))

注意:后续处理流程统一固定使用UTF-8即可,不需要保留原文件的UTF-16编码,避免额外增加多编码判断逻辑。

内容的提问来源于stack exchange,提问作者Nikita

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 03:54:31