这个问题与这个问题有关:Hash keys encoding: Why do I get here with Devel::Peek::Dump two different results?
当我取消注释# utf8::upgrade( $name );
行或注释掉它的$hash{'müller'} = 'magenta';
行时。
#!/usr/bin/env perl
use warnings;
use 5.014;
use utf8;
binmode STDOUT, ':encoding(utf-8)';
use XML::LibXML;
# Hash read in from a file:
# ...
my %hash = ( 'müller' => 'green', 'schneider' => 'blue', 'bäcker' => 'red' );
# ...
# change or add something
$hash{'müller'} = 'magenta';
# writing Hash to xml file
my $doc = XML::LibXML::Document->new('1.0', 'UTF-8' );
my $root = $doc->createElement( 'my_test' );
for my $name ( keys %hash ) {
# utf8::upgrade( $name );
my $tag = $doc->createElement( 'item' );
$tag->setAttribute( 'name' => $name );
my $tag_color = $doc->createElement( 'color' );
$tag_color->appendTextNode( $hash{$name} );
$tag->appendChild( $tag_color );
$root->appendChild( $tag );
}
$doc->setDocumentElement($root);
say $doc->serialize( 1 );
$doc->toFile( 'my_test.xml', 1 );
输出:
error : string is not in UTF-8
encoding error : output conversion failed due to conv error, bytes 0xFC 0x6C 0x6C 0x65
I/O error : encoder error
<?xml version="1.0" encoding="ISO-8859-1"?>
<my_test>
<item name="m
i18n error : output conversion failed due to conv error, bytes 0xFC 0x6C 0x6C 0x65
I/O error : encoder error
答案 0 :(得分:3)
根据XML :: LibXML,'müller' eq 'müller'
是真还是假取决于字符串在内部的存储方式。那是一个错误。具体来说,为UTF8标志分配含义称为“Unicode Bug”,并且记录XML :: LibXML以完全符合this page的“编码支持”部分。
错误是known,但由于向后兼容性原因,无法彻底修复。 Perl提供了两个工具来解决Unicode Bug的实例:
utf8::upgrade( $sv ); # Switch to the UTF8=1 storage format
utf8::downgrade( $sv ); # Switch to the UTF8=0 storage format
前者将是适合在此使用的工具。
sub _up { my ($s) = @_; utf8::ugprade($s); $s }
$tag_color->appendTextNode( _up $hash{$name} );
注意:即使您没有utf8::upgrade
,也可以使用use utf8;
。如果您的源代码是UTF-8,则只能使用use utf8;
。
答案 1 :(得分:2)
如果我将脚本保存为iso-8859-1,则会出现错误。如果我把它保存为utf-8,它就可以了。