Perl: 修复包含八进制或十六进制代码的 utf8 xml 文件

Perl: Repair utf8 xml file which contains octal or hexadecimal codes

我从 Linux-server 在 window10-machine 上得到了一个 xml-file。该文件是 base64 编码的。我使用来自 MIME::Base64 的函数 decode_base64 通过 Perl 脚本解码了 xml。我用 Perl 脚本测试了它是否格式正确,但事实并非如此:

C:\test>perl test_well_formed.pl test.xml
test.xml:3: parser error : Input is not proper UTF-8, indicate encoding !
Bytes: 0xFC 0x6C 0x6C 0x65
<print>M³ller</print>
        ^

我看了看内容。 Notepad++ 将变音符 ü 显示为十六进制代码

<?xml version="1.0" encoding="utf-8" ?>
<test>
<print>MxFCller</print>
</test>

并且 Emacs 将 ü 显示为八进制代码:

<?xml version="1.0" encoding="utf-8" ?>
<test>
<print>M4ller</print>
</test>

Emacs 中的编码是:

 Its value is ‘utf-8-dos’

显然,utf8 中不允许使用十六进制和八进制代码xml。

我想要的是:

<?xml version="1.0" encoding="utf-8" ?>
<test>
<print>Müller</print>
</test>

我的主要问题是:如何修复 xml 文件?

一种解决方案是使用 Perl 脚本逐行读取或 slurp 并将十六进制代码(或八进制代码?)替换为变音符号。或者有更好的修复方法吗?例如,转换base64文件时可以考虑umlaute吗?

第二个问题是:为什么一个编辑器显示八进制代码,另一个显示十六进制代码?

下面是notepad++和Emacs的截图:

您没有“十六进制代码”或“八进制代码”。这就是 Notepad++ 和 Emacs 在文件中显示无效字节的方式。

问题是这与文件不匹配:

<?xml version="1.0" encoding="utf-8"?>

如消息所述,您需要指定正确的编码。例如,如果文件使用 Windows-1252 编码,您应该使用

<?xml version="1.0" encoding="Windows-1252"?>

另一种使它们匹配的方法,可能也是最有意义的方法,是将文件转换为使用 UTF-8。

在 Perl 脚本中,可以使用以下内容:

use Encode qw( from_to );

from_to( $xml, "Windows-1252", "UTF-8" )

在命令行中,这可以使用 iconv 来完成。

iconv -f Windows-1252 -t UTF-8

Why does one editor displays octal codes and the oder hexadecimal codes?

首先,这不是一个不同的数字。

并且因为在编写 Notepad++ 时十六进制是字节的首选表示形式,八进制早已被废弃。