【发布时间】:2014-02-01 12:43:18
【问题描述】:
我的程序从数据源接收 UTF-8 编码的字符串。我需要篡改这些字符串,然后将它们作为 XML 结构的一部分输出。 当我序列化我的 XML 文档时,它将被双重编码并因此被破坏。当我只序列化根元素时,它会很好,但当然缺少标题。
这是一段试图可视化问题的代码:
use strict; use diagnostics; use feature 'unicode_strings';
use utf8; use v5.14; use encoding::warnings;
binmode(STDOUT, ":encoding(UTF-8)"); use open qw( :encoding(UTF-8) :std );
use XML::LibXML
# Simulate actual data source with a UTF-8 encoded file containing '¿Üßıçñíïì'
open( IN, "<", "./input" ); my $string = <IN>; close( IN ); chomp( $string );
$string = "Value of '" . $string . "' has no meaning";
# create example XML document as <response><result>$string</result></response>
my $xml = XML::LibXML::Document->new( "1.0", "UTF-8" );
my $rsp = $xml->createElement( "response" ); $xml->setDocumentElement( $rsp );
$rsp->appendTextChild( "result", $string );
# Try to forward the resulting XML to a receiver. Using STDOUT here, but files/sockets etc. yield the same results
# This will not warn and be encoded correctly but lack the XML header
print( "Just the root document looks good: '" . $xml->documentElement->serialize() . "'\n" );
# This will include the header but wide chars are mangled
print( $xml->serialize() );
# This will even issue a warning from encoding::warnings
print( "The full document looks mangled: '" . $xml->serialize() . "'\n" );
剧透 1:好案例:
'¿Üßıçñíïì' 的值没有意义
剧透 2:坏情况:
'¿ÃÃıçñÃïì' 的值没有意义
根元素及其内容已采用 UTF-8 编码。 XML::LibXML 接受输入并能够对其进行处理并再次将其作为有效的 UTF-8 输出。一旦我尝试序列化整个 XML 文档,里面的宽字符就会被破坏。在十六进制转储中,看起来已经 UTF-8 编码的字符串再次通过 UTF-8 编码器。从Perl's own Unicode tutorial 一直到tchrist's,我已经搜索、尝试和阅读了很多内容,这是Why does modern Perl avoid UTF-8 by default? 问题的最佳答案。不过,我不认为这是一个普遍的 Unicode 问题,而是我和 XML::LibXML 之间的一个特定问题。
我需要做些什么才能输出包含标题的完整 XML 文档,以便其内容保持正确编码?是否有要设置的标志/属性/开关?
(我很乐意接受指向 TFM 相应部分的链接,只要它们真的有用,我就应该拥有 R ;)
【问题讨论】:
-
注意,
use open qw( :encoding(UTF-8) :std );已经做到了binmode(STDOUT, ":encoding(UTF-8)");