为啥必须在 XML 属性中转义 <?

Posted

技术标签:

【中文标题】为啥必须在 XML 属性中转义 <?【英文标题】:Why must < be escaped in an XML attribute?为什么必须在 XML 属性中转义 <? 【发布时间】:2021-12-20 05:51:23 【问题描述】:

我有点想知道为什么&lt; 必须在 XML 属性中转义,例如

<foo bar="3 < 4" />

从周围(标签内部,属性值内部)来看,解析器应该很清楚它不能是新标签的开始。

XML 规范禁止这样做的原因是什么?

【问题讨论】:

【参考方案1】:

小于字符 (&amp;lt;) must 确实是属性值内的escaped:

格式良好的约束:属性值中没有&amp;lt;

直接或间接引用的任何实体的替换文本 在属性值(“&amp;lt;”除外)中不得包含&amp;lt;

为什么?

如您所见,可以明确解析包含&amp;lt; 的属性值。然而,动机是使 XML 的解析规则尽可能简单......

据 XML 1.0 W3C 推荐标准的编辑之一、The Annotated XML Specification 的作者 Tim Bray 所说,它抓住了 XML 设计决策背后的一些基本原理:

消除&amp;lt;

从表面上看,这条规则可能看起来有点不必要 其中。由于属性值中不能有标签,所以有一个

这是让DPH 的生活更轻松的又一次尝试。 XML 中的规则 很简单:当你在阅读文本时,你点击了&amp;lt;,那就是 标记分隔符。不只是有时,总是。当你想要一个在 数据,你必须使用&amp;lt;。不只是有时,总是。在属性中 价值观。

这条规则还有另一个意想不到的有益副作用;它使 捕获某些错误要容易得多。假设你有一大块 XML如下:

&lt;a href="notes.html&gt; &lt;img src='notes.gif'&gt;&lt;/a&gt;

请注意,notes.html 缺少结束引号。没有 no-&amp;lt; 规则,很难检测到这个问题并且 发出合理的错误信息。由于属性值可以包含 几乎任何东西,在处理器发现之前不会检测到错误 下一个引号。相反,您首先会收到一条错误消息 您点击&amp;lt; 的时间,在上面的示例中,在许多情况下,它是 几乎立即。

Back-link to spec

【讨论】:

Tim Bray 的理由相当忽视了 &amp;lt; 在 cmets 和处理指令的内容中被允许的事实...... @MichaelKay ... 以及&gt; 允许的,这也使 DPH 的生活复杂化。但是一个不太好的理由仍然是一个理由,这句话似乎为“什么是原因”这个问题提供了一个客观的答案,而不是更主观的问题“应该排除&amp;lt; 吗?”,我不知道'认为在 SO 的职权范围内无法回答。【参考方案2】:

我不确切知道,但在许多情况下,解释是与 SGML 兼容。 XML 被设计为 SGML 的子集,因此不允许 SGML 不允许的事情。

【讨论】:

但是 SGML 允许在 CDATA 类型的属性值中使用任意字符(终止引号除外)。 PCDATA 不是属性格式之一。 (别问为什么我的书架上还有一本 SGML 手册。)

以上是关于为啥必须在 XML 属性中转义 <?的主要内容,如果未能解决你的问题,请参考以下文章

在 sed/shell 中转义 < 和 >

如何在 T-SQL 中的 XML 字符串中的属性中转义双引号?

使用 xsltproc 转义 XML 属性的值

在 C# 中转义无效的 XML 字符

有没有办法在 xml 中转义 CDATA 结束令牌?

使用 Python 转义 XML 中的未转义字符