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

使用xmltodict解析XML报ExpatError无效令牌错误该如何解决?

问题触发原因
  • 编码识别错误:你调用requests.Response.text时,requests会自动根据响应头猜测内容编码,对欧洲站点的XML文件猜测准确率很低,解码后会生成乱码式的非法字符,expat解析器无法识别。
  • XML内容存在非法内容:包括未转义的XML保留字符(&、<、>等)、XML规范不允许的控制字符、UTF-8 BOM头等,都会触发expat解析报错。
  • stream模式的隐性问题:你开启了stream=True参数但没有按块读取内容,小概率会出现内容截断不完整的情况,也会导致XML非良构。
修复方案

方案1:优先使用二进制内容解析(解决90%以上同类型问题)

xmltodict的parse方法原生支持bytes类型输入,无需手动解码,直接传入响应的二进制内容即可避免编码识别错误,不需要的stream=True参数可直接移除:

import requests
import xmltodict

metadataxml = "https://nedlasting.geonorge.no/geonorge/Tjenestefeed_daglig.xml"

md_response = requests.get(metadataxml)
# 直接传入二进制内容,不要用.text属性
xml = xmltodict.parse(md_response.content)

方案2:预处理过滤非法字符(针对内容本身存在非法字符的情况)

如果方案1仍报错,可先过滤掉XML规范不允许的控制字符再解析:

import re
import requests
import xmltodict

# 匹配XML非法控制字符的正则
illegal_xml_re = re.compile(r'[\x00-\x08\x0b-\x0c\x0e-\x1f]')
metadataxml = "https://nedlasting.geonorge.no/geonorge/Tjenestefeed_daglig.xml"

md_response = requests.get(metadataxml)
# 用utf-8-sig解码自动处理BOM头,再过滤非法字符
md_data = illegal_xml_re.sub('', md_response.content.decode('utf-8-sig'))
xml = xmltodict.parse(md_data)

方案3:使用容错解析器(针对XML本身存在轻微非良构问题)

如果XML存在未转义保留字符等问题,可替换底层解析器为带容错模式的lxml,不需要修改XML内容即可完成解析,需先安装依赖:pip install lxml

import requests
import xmltodict
from lxml import etree

metadataxml = "https://nedlasting.geonorge.no/geonorge/Tjenestefeed_daglig.xml"
md_response = requests.get(metadataxml)
# 配置lxml容错解析器
parser = etree.XMLParser(recover=True)
xml = xmltodict.parse(md_response.content, parser=parser)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 06:36:05