2013-10-30 31 views
3

上个世纪以前,我发现了一些在线的Perl,当它是一个单线时,它整齐地格式化了有效的XML(制表符和换行符)。代码如下。XML :: Twig如何keep_encoding工作?

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

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

按照的Perldoc的keep_encoding

这是一个(略?)邪恶的选项:如果XML文档不是UTF-8 编码,要保持这种方式,然后设置keep_encoding 将对字符使用theExpat 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; 
+1

这里实际上有两件事:XML :: Twig生成什么,然后保存在文件中。 XML :: Twig在perl的内存中产生$ sXML,但与将它保存在文件中无关。 –

+0

谢谢@briandfoy。我会让你现在回到掌握Perl :-) –

回答

5

很难没有你的数据进行测试,但我猜想,这是由于使用Perl打印文件作为ISO-8859-1文件,因为它没有关于它的编码的任何信息(其从XML :: Parser中获取“raw”)。打印前请尝试binmode STDOUT, ':utf8';

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

+0

谢谢,这工作。大多数时候我用Java编写代码,所以我忘记了Perl不默认UTF-8。 –

+1

这是为了向后兼容,如果Perl默认使用utf8打印时,它首先获得unicode支持,它将破坏大量现有代码。还有其他一些方法可以让它默认输出utf8,就像'-C'选项一样。 – mirod