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 ET
<p>def safe_parse_xml(xml_str):</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/ai/1416" title="VidAU"><img
src="https://img.php.cn/upload/ai_manual/000/000/000/175680310252076.png" alt="VidAU" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/ai/1416" title="VidAU">VidAU</a>
<p>VidAU AI 是一款AI驱动的数字人视频创作平台,旨在简化视频内容创作流程</p>
</div>
<a href="/ai/1416" title="VidAU" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div><h1>将孤立 & 替换为 &(但保留已合法的 & < 等)</h1><pre class='brush:php;toolbar:false;'>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 = '
JavaScript里用DOMParser处理含实体的XML字符串
DOMParser对实体更严格,连'都可能报错(除非文档类型声明支持)。安全做法是先用textContent提取原始字符,或改用非验证模式解析。
- 不要依赖
innerHTML或outerHTML反解XML——它们会二次转义 - 若XML来自不可信源,优先用
new DOMParser().parseFromString(xmlStr, 'application/xml'),检查parsererror元素是否存在 - 真正需要保留
'时,在XML顶部显式声明:]>
生成XML时如何避免特殊字符引发问题
核心原则:永远不手动拼接XML字符串。所有内容必须经由序列化接口自动转义。
- Python用
ET.SubElement()+text属性赋值,ET.tostring()会自动处理→<code><等 - JavaScript用
document.createElement()和textContent(不是innerHTML) - 若必须手写,只对
&、、<code>>、"、'做转义,其他Unicode字符(如中文、emoji)可直接保留
容易被忽略的一点:XML声明中的encoding必须与实际字节编码一致,否则即使实体正确,解析器也可能因字节错位误判&位置。









