Получение ошибки кодирования при использовании хеш-ключей для записи XML-файлов с XML :: LibXML - PullRequest
4 голосов
/ 09 декабря 2011

Этот вопрос относится к этому вопросу: Кодировка хэш-ключей: почему я получаю здесь с Devel :: Peek :: Dump два разных результата?
Когда я раскомментирую строку # 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

Ответы [ 2 ]

3 голосов
/ 09 декабря 2011

Согласно XML :: LibXML, значение 'müller' eq 'müller' равно true или false, зависит от того, как строки были сохранены внутри.Это ошибка.В частности, присвоение значения флагу UTF8 известно как «Ошибка Unicode», и документ XML :: LibXML документирован, чтобы сделать именно это в разделе «Поддержка кодирования» этой страницы .

Ошибка известна , но ее нельзя исправить чисто по причинам обратной совместимости.Perl предоставляет два инструмента для работы с экземплярами ошибки Unicode:

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;.Используйте use utf8; только если ваш исходный код UTF-8.

2 голосов
/ 09 декабря 2011

Я получаю ошибку, если сохраню ваш скрипт как iso-8859-1. Если я сохраню его как utf-8, он будет работать.

...