2013-10-30 33 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