XML解析遇&、

XML解析时遇到&、等实体报错怎么办
直接用原生解析器(如Python的xml.etree.ElementTree或JavaScript的DOMParser)加载含未声明或非法实体的XML,会抛出ParseError或SyntaxError。这不是编码问题,而是XML规范强制要求:所有&必须成对出现为合法实体(如&、"),不能孤立存在。
- 最常见诱因是HTML片段混入XML内容(比如
© 2024没转义成©) - 手动拼接XML字符串时漏掉
&转义,例如写成"price=19&tax=2"而非"price=19&tax=2" - 某些老旧系统导出的XML仍使用
'但未在文档头部声明DOCTYPE
Python中用xml.etree.ElementTree安全加载含脏数据的XML
标准ET.parse()不接受自定义实体映射,遇到未知实体直接失败。绕过方法是预处理文本——把孤立&和常见HTML实体兜底转义,再交给解析器。
import re import xml.etree.ElementTree as ETdef safe_parse_xml(xml_str):
将孤立 & 替换为 &(但保留已合法的 & < 等)
xml_str = re.sub(r'&(?!(amp|lt|gt|quot|apos);)', r'&', xml_str) # 补全常见HTML实体(如 © → ©) xml_str = re.sub(r'&([a-zA-Z][a-zA-Z0-9]*);', r'&\1;', xml_str) return ET.fromstring(xml_str)示例:原始字符串含非法 & 和 ©
raw = '
- © 2024 & price=10&unit=kg
' root = safe_parse_xml(raw) print(root.text) # 输出:© 2024 & price=10&unit=kgJavaScript里用
DOMParser处理含实体的XML字符串
DOMParser对实体更严格,连'都可能报错(除非文档类型声明支持)。安全做法是先用textContent提取原始字符,或改用非验证模式解析。
- 不要依赖
innerHTML或outerHTML反解XML——它们会二次转义 - 若XML来自不可信源,优先用
new DOMParser().parseFromString(xmlStr, 'application/xml'),检查parsererror元素是否存在 - 真正需要保留
'时,在XML顶部显式声明:]>
生成XML时如何避免特殊字符引发问题
核心原则:永远不手动拼接XML字符串。所有内容必须经由序列化接口自动转义。
- Python用
ET.SubElement()+text属性赋值,ET.tostring()会自动处理→zuojiankuohaophpcn等 - JavaScript用
document.createElement()和textContent(不是innerHTML) - 若必须手写,只对
&、、>、"、'做转义,其他Unicode字符(如中文、emoji)可直接保留
容易被忽略的一点:XML声明中的encoding必须与实际字节编码一致,否则即使实体正确,解析器也可能因字节错位误判&位置。










