XML::Twig如何使用keep_encoding参数?

4
很久以前,我在网上找到了一些 Perl 代码,它可以将有效的 XML(制表符和换行符)整齐地格式化为单行。该代码如下所示。
它使用 XML::Twig 来实现。它创建了 XML::Twig 对象,没有使用 keep_encoding($twig = XML::Twig->new()),但如果我给它一个带有非 ASCII 字符的 UTF-8 编码的 XML 文件,它会生成一个文件,使用 Ubuntu 上的 isutf8 命令检查后发现它是无效的 UTF-8 编码。打开文件,在 xxd 中看到,该字符由 2 个字节变为 1 个字节。
如果我使用 $twig= XML::Twig->new(keep_encoding=>1);,相同的输入会生成有效的 UTF-8 编码,两个字节也被保留。
根据 keep_encoding 的 Perldoc
这是一个(稍微?)邪恶的选项:如果 XML 文档不是 UTF-8 编码,并且您想保持原样,那么设置 keep_encoding 将使用 Expat original_string 方法进行字符编码,从而保留原始编码以及字符串中的原始实体。
为什么没有这个选项就会生产非 UTF-8 文档?设置它又为什么会使 UTF-8 编码得以保留?
顺便说一下,这里的非 ASCII 字符是不间断空格(c2a0)。
use strict;
use warnings;
use XML::Twig;
my  $sXML  = join "", (<>);
my  $params = [qw(none nsgmls nice indented record record_c)];
my  $sPrettyFormat  = $params->[3] || 'none';
my $twig = XML::Twig->new();
$twig->set_indent(" "x4);
$twig->parse( $sXML );
$twig->set_pretty_print( $sPrettyFormat );
$sXML      = $twig->sprint;
print $xXML;

1
这里实际上有两件事情:XML::Twig生成的内容以及你保存在文件中的内容。XML::Twig在perl内存中生成$sXML,但与你将其保存在文件中无关。 - brian d foy
谢谢@briandfoy。现在我会让您继续掌握Perl :-) - matt freake
1个回答

5
很难在没有数据的情况下进行测试,但我猜测这是由于Perl将文件打印为ISO-8859-1文件,因为它没有关于编码的任何信息(它从XML::Parser中获取“原始”信息)。尝试在打印之前使用binmode STDOUT, ':utf8';。此外,先读取文件然后传递字符串给解析器可能不是一个好主意。更安全的方法是使用parsefile(在文件名上)。这样可以避免潜在的编码问题。

谢谢,那个有效。大多数情况下我都用Java编程,所以我忘记了Perl不默认使用UTF-8。 - matt freake
1
这是为了向后兼容而设置的,如果 Perl 在第一次支持 Unicode 时默认使用 utf8 进行打印,那么就会破坏大量现有的代码。不过,还有其他的方式可以使其默认输出 utf8,例如使用 -C 选项。 - mirod

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