关于.net:使用xml / html上的启发式方法进行编码识别?

Encoding recognition using heuristic methods over xml/html?

假设我有一个存储在远程计算机上的XML文件。我不知道这个文件是如何保存的。(使用了什么编码)。

我想读取这个文件并用那个XML文件做一些操作。

但后来我想:好吧,如果我不知道分析硬盘上的字节,我怎么能从:中读取encoding部分呢?

在与jon进行了一次小讨论之后,我被告知可以在utf-8和utf-16之间自动推断编码,而这些是XML规范规定的唯一可以忽略的。

这让我问:其他编码呢?如果XML保存在encoding-lala中,我怎么知道它?

当乔恩引用我的W3C文章时,我确实找到了一个答案:

The XML encoding declaration functions as an internal label on each
entity, indicating which character encoding is in use. Before an XML
processor can read the internal label, however, it apparently has to
know what character encoding is in use—which is what the internal
label is trying to indicate.

它通过以下方式实现:

Because each XML entity not accompanied by external encoding
information and not in UTF-8 or UTF-16 encoding must begin with an XML
encoding declaration, in which the first characters must be ,
any conforming processor can detect, after two to four octets of
input, which of the following cases apply. In reading this list, it
may help to know that in UCS-4, < is #x0000003C and ? is #x0000003F, and the Byte Order Mark required of UTF-16 data streams is #xFEFF.

因此,它确实使用启发式方法通过尝试获得适当的字符串来获得编码。

另一个帮助它的有用信息是encoding声明的结构:

注意regex,(basic ascii 0..127)字符和encoding字。

enter image description here

所以我的问题是:

即使它保存为utf-8/16/blabla,它也能成功地使用第一个字节识别编码(不管是不是启发式)。

如果是这样,为什么还需要


您需要两个编码来读取XML文件(我不会提到bom,它只是简化事情的另一个提示):

1)第一个编码用于读取XML声明。它更多的是面向字节编码的编码,因为您只需要读取US-ASCII字符。您有一堆字节,需要读取一堆ASCII字符。

请注意,它工作是因为编码名称只能包含US-ASCII字符(IANA字符集)。例如,在那个阶段,您不需要区分utf-8和us-ascii,因为它们以相同的方式编码ascii字符。

因此,这里要测试的编码数量是有限的,因为您关注的是byte->ascii(1 byte->1 char,2 bytes->1 char,4 bytes->1 char等)字符转换,而不是整个Unicode集。您将在此处使用的编码不能用于文件的其余部分。

例如,此时,您将无法区分使用Windows-1252编码的文件和使用ISO-8859-1编码的文件。为此,您需要读取编码名称。

2)第二个编码用于读取文件的其余部分。


这是必要的,因为启发式不能总是完全确定编码将是什么。例如,对于没有进入00 3C 00 3F的字节顺序标记的序列,规范说编码是:

UTF-16BE or big-endian ISO-10646-UCS-2 or other encoding with a 16-bit code unit in big-endian order and ASCII characters encoded as ASCII values (the encoding declaration must be read to determine which)

(增加了重点。)

实际上,在没有字节顺序标记的情况下,在所有情况下(除Other情况外),都必须读取编码声明。只是在规范的文本中并没有特别突出。

如果启发式方法不足以完全确定,那么解析器就足以调整其解码,使其能够读取编码声明并对编码进行最终确定。(说明书上说的也差不多。)