Perl Twig如何保持编码工作?

Perl Twig如何保持编码工作?,perl,utf-8,xml-twig,Perl,Utf 8,Xml Twig,很久以前,我在网上发现了一些Perl,当它是一行时,它可以整齐地格式化有效的XML(制表符和换行符)。代码如下 它使用XML::Twig来实现这一点。它在不使用keep_编码的情况下创建XML::Twig对象($Twig=XML::Twig->new()),但是如果我给它一个UTF-8编码的XML文件,其中包含一个非ASCII字符,它会根据Ubuntu上的isutf8命令生成一个无效的UTF-8文件。在xxd中打开文件,我可以看到字符从2字节变为1字节 如果我使用我的$twig=XML::twi

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

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

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

根据Perldoc进行keep_编码

这是一个(稍微?)邪恶的选项:如果XML文档不是UTF-8 编码并希望保持这种方式,然后设置keep_encoding 将使用expat original_string方法表示字符,从而保持 原始编码以及中的原始实体 字符串

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

顺便说一下,非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;
使用严格;
使用警告;
使用XML::Twig;
我的$sXML=加入“”();
my$params=[qw(无nsgmls良好缩进记录_c)];
my$sPrettyFormat=$params->[3]| |“无”;
my$twig=XML::twig->new();
$twig->set_缩进(““x4”);
$twig->parse($sXML);
$twig->set\u pretty\u print($sPrettyFormat);
$sXML=$twig->sprint;
打印$xXML;

没有数据很难进行测试,但我猜这是因为Perl将文件打印为ISO-8859-1文件,因为它没有任何编码信息(它从XML::Parser获取“原始”数据)。尝试
binmode标准输出':utf8'打印前


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

这里实际上有两件事:XML::Twig生成的内容以及随后保存在文件中的内容。Twig在perl内存中生成$sXML,但与将其保存在文件中无关。谢谢@briandfoy。我现在让您回到掌握Perl的话题:-)谢谢,这很有效。大多数时候我用Java编码,所以我忘记了Perl并没有默认为UTF-8。这是为了向后兼容,如果Perl在第一次获得unicode支持时默认为使用utf8打印,它会破坏很多现有代码。还有其他方法可以使其默认输出utf8,比如
-C
选项。