简短的回答
在没有外部编码信息的 UTF-8 编码文档的非常特殊的情况下(我从 cmets 了解到这是您感兴趣的内容),这两种声明之间没有区别。
不过,长答案要有趣得多。
规范是怎么说的
如果您查看Appendix F1 of the XML specification,则说明了在没有外部编码信息时确定编码应遵循的过程。
如果文档被编码为 UTF 变体之一,解析器应该能够从字节顺序标记或 XML 声明的开头检测前 4 个字节内的编码。
但是,根据规范,它仍然应该读取编码声明。
在上述不需要读取编码声明来确定编码的情况下,第 4.3.3 节仍然要求读取编码声明(如果存在)并检查编码名称以匹配实体的实际编码.
如果不匹配,根据section 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 字符在 Latin1 中无效的事实只是意味着它们在字符解码级别被静默删除。
这不适用于 UTF-8 文档上所有声明的编码。如果声明的编码是 UTF-16,我们将返回 Opera、Firefox 和 Chrome 忽略声明的编码,而 Internet Explorer 返回一个空白文档。
基本上,任何让 IE 返回空白文档的东西都会让其他浏览器忽略声明的编码。
其他不一致的地方
还值得一提的是字节顺序标记的重要性。根据section 4.3.3 of the spec:
以 UTF-16 编码的实体必须 [...] 以字节顺序标记开头
但是,如果您尝试读取没有 BOM 的 UTF-16 编码的 XML 文档,大多数浏览器仍然会接受它为有效的。只有 Firefox 将其报告为 XML 解析错误。
外部编码信息
到目前为止,我们一直在考虑没有外部编码信息时会发生什么,但是,正如其他人所提到的,如果文档是通过 HTTP 接收或包含在某种 MIME 信封中,则编码信息来自这些来源应优先于文档编码。
RFC3023 中描述了各种 XML MIME 类型的大部分细节。但是,实际情况与指定的有所不同。
首先,带有省略字符集参数的 text/xml 应使用 US-ASCII 字符集,但该要求几乎总是被忽略。浏览器通常会使用 XML 编码声明的值,如果没有,则默认为 UTF-8。
其次,如果文档上有 UTF-8 BOM,并且 XML 编码声明是 UTF-8 或不包括在内,则文档将被解释为 UTF-8,无论 Content- 中使用的字符集如何输入。
只有在没有 BOM 并且在 Content-Type 中指定了明确的字符集时,才会优先使用来自 Content-Type 的编码。
无论如何,在 UTF-8 文档中包含 UTF-8 XML 编码声明与根本没有编码声明没有任何不同(涉及 Content-Type)。