我知道XML的默认编码是UTF-8.所有XML消费者都必须等等.因此,这不仅仅是XML是否具有默认编码的问题.
我也知道文档开头的XML-Declarataion<?xml version="1.0" ... ?>
是可选的.并且指定其中的编码也是可选的.
所以我问自己,以下两个XML声明是否是完全相同的两个表达式:
<?xml version="1.0"?>
<?xml version="1.0" encoding="UTF-8"?>
Run Code Online (Sandbox Code Playgroud)
根据我自己目前的理解,我会说这些是等价的,但我不知道.是否已在某处指定了这两个声明的等效性?
(考虑这两个示例行,每个行都是XML文档的第一行,前面是任意(零)字节,并且是UTF-8编码的)
简答
在没有外部编码信息的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蜜蜂).如果您关闭了编码声明,那就没问题了.
从技术上讲,我认为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信封中,那么这些来源的编码信息应该是优先于文档编码.
RFC3023中描述了各种XML MIME类型的大部分细节.然而,现实与指定的有些不同.
首先,带有省略的charset参数的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文档上包含UTF-8 XML编码声明与根本没有编码声明有任何不同.
孤立地,两者都是等价的.您已经引用了规范的相关部分,这些部分表明两个声明都是等效的.
但是,XML可以有一个信封,例如HTTP Content-Type
标头.W3C指定此信封信息优先于文件中的任何其他声明.例如,如果您通过http检索XML,则可能会得到以下结果:
HTTP/1.1 200 OK
Content-Type: text/xml
<root/>
Run Code Online (Sandbox Code Playgroud)
在这种情况下,XML应该读作ascii,因为text/*
mime类型的默认字符集是ascii.这就是你应该使用application/xml
mime类型的原因 - 这些默认为utf-8."application"前缀表示相关的应用程序规范定义了默认编码等内容.(即XML规范接管.)对于text/*
mime类型,默认为ascii,并且charset
参数必须包含在mime类型中才能更改charset.
这是另一个案例:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=win-1252
<?xml version="1.0" encoding="utf-8"?>
<root/>
Run Code Online (Sandbox Code Playgroud)
在这种情况下,符合标准的XML处理器应该读取此文件win-1252
,而不是 utf-8
.
另一个案例:
HTTP/1.1 200 OK
Content-Type: application/xml
<?xml version="1.0" encoding="win-1252"?>
<root/>
Run Code Online (Sandbox Code Playgroud)
这里的编码是win-1252
.
HTTP/1.1 200 OK
Content-Type: application/xml; charset=ascii
<?xml version="1.0" encoding="win-1252"?>
<root/>
Run Code Online (Sandbox Code Playgroud)
这里的编码是ascii
.
归档时间: |
|
查看次数: |
7818 次 |
最近记录: |