XML声明编码

4
它实际上是做什么的?在我很基础的理解水平上,XML只是格式化的文本。因此没有二进制<->文本转换涉及。我强烈怀疑UTF-8和ASCII编码之间唯一的区别是ASCII编码会让XML编写器更加努力地将所有非ASCII字符转换为XML实体,而不仅仅是保留的XML字符。因此,ASCII编码的XML仍然可以包含UTF-8字符,只是它会稍微长一些并且难看一些。
还是有其他功能吗?
更新:
我完全理解如何通过编码将单个字符转换为字节。然而,XML只是文本标记,并且在任何时候都不会这样做。
问题真正是为什么XML编码值存储在XML中?或者XML读取器需要知道哪种编码用于特定的XML文档的情况是什么?

1
“UTF-8字符”这个说法并不存在。你可能指的是非ASCII Unicode字符。而声明的原因是因为有很多不同的编码,比如windows-1250或latin-2。UTF-8和ASCII并不是唯一的两个选项。 - svick
好的,但是为什么XML声明需要首先进行编码呢? - Ilia G
1
因为当您想要读取文件并将其显示给用户时,您需要知道如何将字节解码为字符。 - svick
3个回答

9
请参阅XML规范中的附录F,“字符编码的自动检测”。
特别地,“XML编码值存储在XML中”,因为默认情况下,XML处理器必须假定内容是UTF-16或UTF-8,如果XML文档外部没有找到元数据的话。XML声明是为这种情况设计的,其中没有出现这样的元数据。
XML处理编码的另一个优点是,这样,XML处理器只需要支持两种编码,即UTF-8和UTF-16。如果处理器发现文档处于不支持的编码中(无论是在外部元数据还是在XML声明中),它可以更快地失败,而不是继续读取文档(长时间在声明后)并遇到使用实现相关的启发式方法检测到的意外字节序列。

1
哦哦哦...这实际上有点可怕。因此,在读取文件(字节流)时,XML编码可以用作提示来确定文件编码。在实现方面似乎非常神奇。虽然我想,由于文件编码必须支持字符集,不小于用于XML编码的字符集,这将是一个有效的假设。 - Ilia G
1
它比其他选择不那么神奇。如果我们从磁盘读取逗号分隔的 .txt 文件,绝对没有标准方法可以确定编码方式,这必须是应用程序特定的。使用 XML,我可以为您提供一个 UTF-8 文档、一个 ISO-8859-1 文档和一个 UTF-16 文档,并且通过正确的 XML 声明,我可以确保您正确实现的 XML API 不会有任何问题读取它们。 - Jason Viers
@PeterO。如果文件通过HTTP发送,并且使用Content-Type: text/xml; charset=ISO-8859-1,但XML文档本身声称它是UTF-8,那该怎么办? - Pacerier
@Pacerier:在这种情况下,HTTP头部的内容类型声明优先于文档本身的任何字符编码声明。因此,文档可能会被错误解释。有关更多信息,请参见权威元数据:"在封装容器(例如HTTP头)中接收到的元数据必须被视为权威,并优先使用而不是通过检查数据(例如文档的自我声明编码)找到的元数据。" - Peter O.

4
我强烈建议阅读The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)。您说XML只是“文本”,好像这样就可以简单处理一切,但即使知道它是文本而不是某种结构化二进制格式,也并不意味着您确切地知道如何读取它或其中有哪些字符。
这不是一个“去读手册!”的答案,我相信建立这个基础的难点会有助于解释为什么XML声明存在。
“XML声明需要编码吗?”这是文章中讨论的一个想法之一,但在这里值得强调:所有文本都有编码。“纯文本”根本不存在。 ASCII一种编码,即使我们大多数时候没有考虑它。历史上,我们通常把脑袋埋在沙子里,假设一切都是ASCII,但在今天这种情况下这是不可行的。 XML声明的编码对我们有所帮助,而.txt文件没有任何指示其编码的东西。

我仍然不明白这些与XML有何关联。从XML的角度来看,字符只是字符而已。它是1个字节、2个字节还是3个字节?这取决于底层框架。如果我将我的XML声明为<?xml version="1.0" encoding="ASCII" ?>,这是否意味着它不能包含Unicode字符?当然可以,它们只会被转换为XML实体。事实上,我不知道读取XML的程序为什么需要关注声明编码值。这对于XML编写者来说肯定很重要,但是为什么要存储它呢?只是为了记账吗? - Ilia G
1
从定义标签和属性的角度来看,你是正确的,它并不关心字符编码。通常,XML库将仅在程序端使用UTF-8 - 当您提供数据以创建文档或获取数据时,它必须是UTF-8。编码在XML序列化中发挥作用,这也是规范的一部分。 XML规范与将数据转换为字节流的想法完全分离,它也有规则来执行此操作。例如,所有XML解析器必须支持UTF-8。 - Jason Viers
如果是指XML文档的抽象模型,你所说的是正确的。但实际上,XML文档必须存储在某个地方,可以是内存或文件中。因此,您需要选择一种字符串编码约定。XML声明指定了在将XML文档序列化为文本文件时使用的编码方式。 - ChrisJ
@ChrisJ 不正确。我可以轻松编写一个使用 ASCII XML 编码的代码,但将其写入文件时采用 UTF-8 编码。 - Ilia G
XML标准确实包括XML的物理结构和编码。 - Oliver Meyer
显示剩余2条评论

2
是的,XML文件是一个文本文件,即一系列字符。文件是一系列字节。那么如何将单个字符编码,即转换为一系列字节?有几种将字符编码为字节的方法;“编码”声明指示使用哪种方法。
因此,“编码”声明起着非常重要的作用:人们必须知道使用了哪种编码才能仅仅从文件中读取字符。如果没有指定编码,XML具有一组默认编码,这取决于是否存在“字节顺序标记”(BOM)。如果没有BOM,则默认编码为UTF-8。
ASCII是最简单的编码形式之一。它只能表示128个基本拉丁字符。UTF-8更为复杂;它可以表示所有的Unicode字符集。所以你是正确的,如果你使用ASCII,你必须使用XML实体来表示存在于Unicode但不存在于ASCII中的大量字符。

我仍然感到困惑。XML声明与文件有什么关系?还是包括内存在内的任何存储方式? XML只是文本。包含XML字符串的编码写入文件似乎与其内容完全无关。 - Ilia G
你说“XML只是文本”,这是绝对正确的。但是,为了在计算机中存储任何文本部分,您必须将每个字符映射到一个代码(实际上是一系列字节)。这样的映射称为编码。因此,任何文本文件都是根据编码编写的。要读取文件,您需要知道用于编写的编码。 - ChrisJ
在您更新问题后,有新的评论:您似乎认为文本文件可以根据编写时使用的编码进行读取。不幸的是,这并不正确。没有所谓的文件系统“元数据”指定文本文件的编码。因此,读取可能使用各种编码的文本文件的程序必须使用文件本身的内容来推断使用的编码。这就是存在于文件内部的XML编码声明的原因。 - ChrisJ
我认为这是理所当然的,因为这通常可以通过使用BOM或做出假设或预定义协议来解决。 - Ilia G
可能有这种情况,但通常不是这样的。例如,在UTF-8、ASCII或ISO-8859-x中都没有BOM/编码标记。同样,UTF-16可能带有或不带有BOM,并且可以是大端或小端。那么在没有BOM的情况下,读者该如何做呢?首先,使用<xml字符串编码的方式可以进行一些假设,例如它是8位(或可变长度)还是16位。然后再读取编码声明。请注意,这一切之所以能够实现,是因为许多编码彼此相近,即UTF-8和ISO-8859-x是ASCII的“扩展”。 - ChrisJ
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接