4

很久以前,我在网上发现了一些 Perl,当它是单行时,它整齐地格式化了有效的 XML(制表符和换行符)。代码如下。

它使用 XML::Twig 来做到这一点。它创建没有keep_encoding ( )的 XML::Twig 对象,$twig = XML::Twig->new()但是如果我给它一个 UTF-8 编码的 XML 文件,其中包含一个非 ASCII 字符,它会根据 isutf8 命令生成一个无效的 UTF-8文件Ubuntu。在 xxd 中打开文件,我可以看到字符从 2 字节变为 1。

如果我使用$twig= XML::Twig->new(keep_encoding=>1);相同的输入会产生有效的 UTF-8 并保留两个字节。

根据 Perldoc for keep_encoding

这是一个(有点?)邪恶的选择:如果 XML 文档不是 UTF-8 编码的并且您想保持这种方式,那么设置 keep_encoding 将使用 Expat original_string 方法来处理字符,从而保持原始编码,以及字符串中的原始实体。

为什么在没有该选项的情况下生成非 UTF-8 文档,为什么设置它会导致 UTF-8 特性被保留?

顺便说一下,非ASCII字符是一个不间断的空格(c2 a0)。

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;
4

1 回答 1

5

没有您的数据很难测试,但我猜这是由于 Perl 将文件打印为 ISO-8859-1 文件,因为它没有任何关于其编码的信息(它从 XML 获取“原始” ::解析器)。binmode STDOUT, ':utf8';打印前尝试。

此外,先读取文件然后将字符串传递给解析器可能不是一个好主意。使用parsefile(在文件名上)更安全。您可能会避免编码问题。

于 2013-10-30T18:08:56.423 回答