gio*_*ano 0 xml emacs perl utf-8 utf-16
我已经发布了一个xml-utf16问题, 如果我打开xml文件,Emacs会显示中文字符, 但现在我想解读为什么会出现这种问题.也许,如果我有更深入的了解,我可以更好地应对这类问题.
具体来说,我得到了一个用utf16编码的xml文件.我使用emacs(记事本,firefox)从windows xp PC打开文件,显示图(A)(firefox说:格式不正确).显然,该文件是使用utf16编码导出的.(B)显示十六进制版本.(C)使用emacs(revert-buffer-with-coding-system)转换为utf-8后显示xml文件.我还将带有Perl的xml-utf16文件转换为utf8.结果显示在(D)中.

我的问题:
谢谢你的耐心等待.
为什么utf-8不理解这种编码?
是吧?UTF-8是一种编码.它不懂编码.你的编辑器是理解编码的,它对UTF-8,UTF-16le和UTF-16be的理解不一定相关.
为什么编辑会显示汉字?
(A)中的问题是您的编辑器使用UTF-16be来解码使用UTF-16le编码的文档.
我错了还是这个问题(插入"@")由于xml文件的规范错误?
该文件是正确的.该文件使用UTF-16le.它指定它使用UTF-16le encoding="utf-16"和BOM.
(C)中的问题是您的编辑器使用单字节编码来解码使用UTF-16le编码的文档.^@代表一个NUL.
为什么字符之间的十六进制版本有一点?
没有.最右边的列显示使用US-ASCII解码的文件的内容,这显然不是.
如果我想看一下考虑树结构的utf16/utf8 xml文件
...然后你需要一个XML查看器/编辑器,它以该形式显示XML,而不是文本编辑器.
为什么导出数据并生成正在研究的xml文件的导出器在编辑器打开时不考虑LF/CR获取可读的xml文件?
简单.
有关utf16的辩论
完全相同的问题发生在UTF-8级别,因为人们没有正确处理字形.如果你正确处理字形,UTF-16的"问题"就会消失.
因此,拒绝UTF-16是因为它是一种可变宽度编码而很少有人认为它对我来说没有意义,因为它对于UTF-8来说是相同的.
为什么程序员仍然使用utf16?我错过了什么吗?
这是Windows内部使用的.
我想建议我的数据传递者使用utf8
对于您在emacs中错误地使用UTF-16be而不是UTF-16le而言,这似乎是一个相当激烈的解决方案.
你似乎不知道有各种各样的事情:
这只是Joel Spolsky的"绝对最低限度,每个软件开发人员绝对必须知道关于Unicode和字符集(没有借口!)"的链接.
TL; DR:编码是双射部分函数,它将字节序列映射到字符序列并再次返回.Unicode是一个很大的字符列表,每个字符都有一个数字(代码点).各种编码用于将这些代码点映射到字节:
0xFEFF或0xFFFE排序,其中一个在每个UTF-16文档之前.某些字符("控制字符")没有可打印的解释.在你的hexdump中,不可打印的字节用a表示..Emacs和Vim遵循传统的控制代码前缀路由^,这意味着它与下一个字符一起代表控制代码.^@表示NUL字符,^H表示退格,^D表示传输的结束.通过0x40从可视化表示中的ASCII字符中减去,可以获得控制字符的ASCII值.\377是八进制表示0xFF.
XML的默认编码是UTF-8,因为它向后兼容ASCII.使用任何其他编码是不必要的痛苦,正如这个问题所证明的那样.总之,UTF-16 可以被使用,如果正确申报(您输入尝试它),但后来被搞砸.
您的文件包含以下部分:
0xFFFE,这意味着第一个字节是输入中的低字节.然后是ASCII字符后跟一个NUL字节.0d00 0d0a.0d00是CR,回车.第二部分意味着0a00,换行.它们一起构成了Windows系列的结尾.这0d0a将是一个ASCII CRLF.但这是错误的,因为UTF-16是一个双字节编码.发生了什么:
有人打印出以UTF-16le编码的XML前导码.将\n在年底被自动翻译成\r\n.所以0d00 0a00成了0d00 0d0a 00.
当您不解码输入时,可能会在Perl中发生这种情况,但会对输出进行编码.在Windows上,Perl会自动进行换行,这可以通过以下方式关闭binmode $fh.
如果你的脚本能解决这个错误,那么它做反向同样的错误(翻译\r\n来\n,并随后对其进行解码).
通过直接解码所有输入并在打印之前再次对其进行编码,可以避免此类错误.在内部,始终对代码点进行操作,而不是字节.在Perl中,编码可以添加到文件句柄中binmode,它可以透明地执行解码和编码.