我需要在 XML 文档中转义哪些字符?

Posted

技术标签:

【中文标题】我需要在 XML 文档中转义哪些字符?【英文标题】:What characters do I need to escape in XML documents? 【发布时间】:2010-11-08 16:22:07 【问题描述】:

在 XML 文档中必须转义哪些字符,或者我在哪里可以找到这样的列表?

【问题讨论】:

示例:<company>AT&T</company> 请参阅下面的 Simplified XML Escaping,了解我从主要来源 (W3C Extensible Markup Language (XML) 1.0 (Fifth Edition)) 中提炼的简明易记指南。 从字面上看,这里没有一个答案是正确的。您还必须在 XML 1.1 中转义许多不同的控制字符。 @JasonC:按预期而不是字面理解问题是理想的。如果您认为未来的读者会受益于如何在 XML 中指定控制字符的详细说明,请在答案中详细说明。谢谢。 @kjhughes 问题被解释为预期,这里的答案都不是正确的。您还必须转义 XML 1.1 中的许多不同控制字符,如here 所述。有关具体细节和限制,另请参阅 XML 1.1 §4.1、§4.4、§4.6 和 Appx. C。 【参考方案1】:

如果您使用适当的类或库,它们会为您进行转义。许多 XML 问题是由字符串连接引起的。

XML 转义字符

只有五个:

"   "
'   '
<   &lt;
>   &gt;
&   &amp;

转义字符取决于特殊字符的使用位置。

可以在W3C Markup Validation Service 验证示例。

文字

安全的方法是转义文本中的所有五个字符。但是,"'&gt; 这三个字符在文本中不需要转义:

<?xml version="1.0"?>
<valid>"'></valid>

属性

安全的方法是转义属性中的所有五个字符。但是,&gt; 字符不需要在属性中转义:

<?xml version="1.0"?>
<valid attribute=">"/>

如果引号是",则' 字符不需要在属性中转义:

<?xml version="1.0"?>
<valid attribute="'"/>

同样,如果引号是',则" 不需要在属性中转义:

<?xml version="1.0"?>
<valid attribute='"'/>

评论

所有五个特殊字符不得在 cmets 中转义:

<?xml version="1.0"?>
<valid>
<!-- "'<>& -->
</valid>

CDATA

所有五个特殊字符不得在CDATA 部分中转义:

<?xml version="1.0"?>
<valid>
<![CDATA["'<>&]]>
</valid>

处理说明

所有五个特殊字符不得在 XML 处理指令中转义:

<?xml version="1.0"?>
<?process <"'&> ?>
<valid/>

XML 与 html

HTML 有 its own set of escape codes 覆盖更多字符。

【讨论】:

@Pacerier,我求你不要编写自己的 XML/HTML 转义代码。使用库函数,否则你一定会错过一个特殊情况。 对于换行符,您需要使用 和 对于制表符,如果您在属性中需要这些字符。 如果您要对这些进行查找/替换,请记住执行 &在其他人之前替换。 @Doug 我正要提到完全相同的东西 - 否则所有其他被替换的字符都会被损坏,并且像 &amp;amp;quot; 这样的东西将被更改为 &amp;amp;quot; 来自***:“所有允许的 Unicode 字符都可以用数字字符引用表示。”所以有很多超过 5 个。【参考方案2】:

也许这会有所帮助:

List of XML and HTML character entity references:

在 SGML、HTML 和 XML 文档中, 称为字符的逻辑结构 数据和属性值包括 字符序列,其中每个 性格可以直接显现 (代表自己),或者可以是 由一系列字符表示 称为字符引用,其中 有两种类型:数字 字符参考和字符 实体参考。本文列出 字符实体引用 在 HTML 和 XML 文档中有效。

那篇文章列出了以下五个预定义的 XML 实体:

quot  "
amp   &
apos  '
lt    <
gt    >

【讨论】:

【参考方案3】:

除了常见的五个字符[、&、“和'],我还要转义垂直制表符(0x0B)。它是有效的UTF-8,但不是有效的XML 1.0,并且甚至许多库(包括高度可移植 (ANSI C) 库 libxml2)都错过了它并默默地输出无效的 XML。

【讨论】:

【参考方案4】:

根据万维网联盟 (w3C) 的规范 there are 5 characters that must not appear in their literal form in an XML document,除非用作标记分隔符或在注释、处理指令或 CDATA 部分中。在所有其他情况下,必须根据下表使用相应的实体或数字引用替换这些字符:

原始字符​​strong>XML实体替换XML数字替换< < >                            > > kbd> “ kbd> ” kbd> &#34; kbd> & kbd> &amp ; KBD> &#38; KBD> ' KBD> ' KBD> &#39; KBD>

请注意,除了 ' 之外,上述实体也可以在 HTML 中使用,它是在 XHTML 1.0 中引入但在 HTML 4 中未声明的。因此,为了确保复古兼容性,the XHTML specification recommends the use of &#39;。

【讨论】:

XML 预定义了这五个实体,但它绝对没有指定您不能以文字形式使用这五个字符中的任何一个。 实际上不必转义。 如上所述,当用作标记分隔符或在注释、处理指令或 CDATA 部分中时, " & ' 不必转义。即,当您使用 作为XML 标记,您不会对其进行转义。注释也是如此(您是否会在 XML 文件的注释行中转义 & ?您不需要,如果您不这样做,您的 XML 仍然有效)。这个在official recommendations for XML by W3C 中明确指定。 @ShaunMcCance &gt; 如果在内容中跟在]] 之后,则必须对其进行转义,除非它打算成为指示CDATA 部分结束的]]&gt; 分隔符的一部分。 不是死灵法师,但@Albz 说这些字符必须在内容中实体化是不正确的。请参阅w3.org/TR/REC-xml/#NT-CharData 的第 2.4 节。 TL;DR 版本是在 chardata 元素内容中,&和 <必须始终被实体化。 >字符可以实体化,尽管它必须出现在文字字符串“]]>”中,否则将被读取为结束 CDATA 部分。对于单引号和双引号,您可以根据需要进行转义。就是这样,对于元素内部的 chardata。 XML 的其他组件有其他规则。【参考方案5】:

标签和属性的转义字符不同。

对于标签:

 < &lt;
 > &gt; (only for compatibility, read below)
 & &amp;

对于属性:

" &quot;
' &apos;

来自Character Data and Markup

& 符号 (&) 和左尖括号 () 可以使用 字符串“>”,并且为了兼容性,必须使用以下任一方法进行转义 " > " 或出现在字符串 " ]]> 中的字符引用 " 在内容中,当该字符串未标记 CDATA 的结尾时 部分。

要允许属性值同时包含单引号和双引号, 撇号或单引号字符 (') 可以表示为 " ’ ",双引号 (") 为 " " "。

【讨论】:

这意味着对于属性只有引号需要转义,但这是对其他三个字符的补充【参考方案6】:

只有&lt;&amp; 被视为字符数据而不是标记时需要转义:

2.4 Character Data and Markup

【讨论】:

【参考方案7】:

摘自:XML, Escaping

有五个预定义的实体:

&lt; represents "<"
&gt; represents ">"
&amp; represents "&"
&apos; represents '
&quot; represents "

“所有允许的 Unicode 字符都可以用数字字符引用来表示。” 例如:

&#20013;

大多数控制字符和其他 Unicode 范围都被明确排除,这意味着(我认为)它们不能转义或直接出现:

Valid characters in XML

【讨论】:

【参考方案8】:

这取决于上下文。对于内容,它是 &,以及 ]]>(虽然是三个而不是一个字符的字符串)。

对于属性值,分别是&"'

对于 CDATA,它是 ]]>

【讨论】:

【参考方案9】:

对旧的常见问题的新的简化答案...

简化的 XML 转义 (优先,100% 完成)

    Always (90% 需要记住)

    &amp;lt; 转义为&amp;lt;,除非&amp;lt; 正在启动&lt;tag/&gt; 或其他标记。 将&amp;amp; 转义为&amp;amp;,除非&amp;amp; 正在启动&amp;entity;

    Attribute Values (需要记住 9%)

    attr="'单引号'在双引号内可以。" attr='"双引号"可以在单引号内。'" 转义为&amp;quot;,将' 转义为&amp;apos;,否则。

    Comments、CDATA 和 Processing Instructions (需要记住 0.9%)

    &lt;!-- comments --&gt; 内没有任何内容必须转义,但不允许使用 -- 字符串。 &lt;![CDATA[ CDATA ]]&amp;gt; 内没有任何内容必须转义,但不允许使用 ]]&amp;gt; 字符串。 &lt;?PITarget PIs ?&gt; 内没有任何内容必须转义,但不允许使用 ?&gt; 字符串。

    Esoterica (需要记住 0.1%)

    在 XML 1.1 中通过 Base64 或 Numeric Character References 转义 control codes。 将]]&amp;gt; 转义为]]&amp;gt;,除非]]&amp;gt; 正在结束CDATA section。 (此规则通常适用于字符数据——甚至在 CDATA 部分之外。)

【讨论】:

另一条值得注意的规则:]]&amp;gt; 必须转义为 ]]&amp;gt;,即使不在 CDATA 部分中也是如此。实现这一目标的最简单方法可能是总是&amp;gt; 转义为&amp;gt; 谢谢,@MichaelKay。我已经合并了您关于 ]]&amp;gt; 的有用说明,但选择将其归类为 esoterica,而不是建议将 &amp;gt; 总是 转义(如您所知,它不必如此)。我的目标是让 XML 转义规则容易记住 100% 准确 . 上述答案包括接受的一个提到所有五个字符都应该在属性内转义。你有没有参考 XML 标准来支持你所说的,因为你的答案在逻辑上似乎是正确的? @RomanSusi:是的,许多其他答案都包含基于对官方 XML BNF 的传闻、误解或误解的错误或过度概括(“安全方式...”)。我的回答是(a)100% 被 W3C XML 推荐证明;查看对官方 BNF 的许多链接引用,并且 (b) 以简洁、合乎逻辑且易于记忆的这些要求的顺序进行组织。 @RomanSusi:“所有五个字符都应在属性内转义”的具体声明是草率的指导,不受官方 BNF 规则支持的 AttValue 在我的回答中通过 2 上的链接引用. Attribute Values.【参考方案10】:

接受的答案不正确。最好是使用库来转义 xml。

正如other question中提到的那样

“基本上,控制字符和超出Unicode范围的字符是不允许的。这也意味着禁止调用例如字符实体。”

如果你只转义五个字符。你可能会遇到An invalid XML character (Unicode: 0xc) was found

这样的问题

【讨论】:

以上是关于我需要在 XML 文档中转义哪些字符?的主要内容,如果未能解决你的问题,请参考以下文章

Android - 我啥时候应该在 Strings.xml 资源文件中转义 unicode?

在 sed/shell 中转义 < 和 >

在 XSLT 中的字符串中转义“&”

应该在正则表达式中转义哪些文字字符?

不需要在 javascript 中转义 innerHTML 字符?

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