简短回答
在特定情况下,即UTF-8编码的文档没有外部编码信息(据评论所述,这是你感兴趣的内容),两个声明之间没有区别。
不过,长答案更有趣。
规范说明
如果查看XML规范的附录F1,就可以了解确定没有外部编码信息时应遵循的处理过程。
如果文档编码为UTF变体之一,解析器应该能够在前4个字节内检测到编码,无论是从字节顺序标记还是XML声明开始。
但是,根据规范,它仍应读取编码声明。
在不需要读取编码声明以确定编码的情况下,仍然需要按照第4.3.3节的要求读取编码声明(如果存在)并检查编码名称是否与实体的实际编码匹配。
如果它们不匹配,根据
第4.3.3节的规定:
“...对于在声明中命名的编码之外的编码呈现给XML处理器的实体(包括编码声明),是致命错误。”
编码为UTF-16,声明为UTF-8
让我们看看当我们创建一个以UTF-16编码但编码声明设置为UTF-8的XML文档时,在现实中会发生什么。
Opera,Firefox和Chrome都将文档解释为UTF-16,忽略编码声明。Internet Explorer(至少版本9)显示空白文档,但没有实际错误。
因此,如果您在UTF-8文档上包含了UTF-8编码声明,并且后来有人将其转换为UTF-16,它将在大多数浏览器中工作,但在IE(以及我假设的大多数Microsoft XML API)中失败。如果您没有包含编码声明,那么您将没有问题。
从技术上讲,我认为IE是最准确的。它没有显示错误可能是因为错误发生在编码层而不是XML层。它假定尽力将UTF-16字符解释为UTF-8,无法找到任何可解码的字符,并最终向XML解析器传递一个空字符序列。
以其他方式声明编码的UTF-8
你现在可能认为Firefox、Chrome和Opera完全忽略了编码声明,但并非总是如此。
如果将文档编码为UTF-8(带有字节顺序标记,因此不会被误认为是其他格式),但将编码声明设置为Latin1,则所有浏览器都将成功将内容解码为Latin1,忽略UTF-8 BOM。
对我来说,这似乎是正确的。BOM字符在Latin1中无效,这意味着它们在字符解码级别上被静默丢弃。
但是,这并不适用于UTF-8文档上的所有声明编码。如果声明的编码为UTF-16,则Opera、Firefox和Chrome将忽略已声明的编码,而Internet Explorer将返回一个空文档。
基本上,任何导致IE返回空白文档的因素都会使其他浏览器忽略已声明的编码。
其他不一致之处也值得一提。根据规范
第4.3.3节的规定:
实体编码为UTF-16必须以字节顺序标记开头。
然而,如果您尝试读取一个没有BOM的UTF-16编码的XML文档,大多数浏览器仍然会将其视为有效。只有Firefox会报告它为XML解析错误。
到目前为止,我们一直在考虑没有外部编码信息时会发生什么,但正如其他人所提到的,如果文档通过HTTP接收或包含在某种MIME信封中,这些来源的编码信息应优先于文档编码。
各种XML MIME类型的大部分细节都在
RFC3023中描述。然而,现实情况与规定有所不同。
首先,省略字符集参数的text/xml应使用US-ASCII字符集,但这一要求几乎总是被忽略。浏览器通常会使用XML编码声明的值,如果没有则默认为UTF-8。
其次,如果文档上有UTF-8 BOM,并且XML编码声明为UTF-8或未包含,则无论Content-Type中使用的字符集如何,文档都将被解释为UTF-8。
唯一情况下Content-Type中的编码似乎具有优先权是当没有BOM并且在Content-Type中指定了显式字符集时。
无论如何,在任何涉及Content-Type的情况下,将UTF-8 XML编码声明包含在UTF-8文档中与不包含编码声明没有任何区别。
<café>
这样。 - Joop Eggen