Perl XML :: Проблема кодирования парсера - PullRequest
1 голос
/ 19 марта 2011

Я пишу Perl-скрипт, который должен извлечь некоторые данные из файла XML.

Сам файл XML кодируется с использованием UTF-8. Однако по какой-то причине то, что я извлекаю из файла, в конечном итоге кодируется как ISO-8859-1. В документации говорится, что все, что передается моим обработчикам, должно быть UTF-8, но это не так.

Парсер в основном что-то вроде этого:

my $parser = XML::Parser->new( Handlers => {
    # Some unrelated handlers here
    Char => sub {
        my ( $expat, $string ) = @_;
        if ( exists $data->{$curId}{$curField} ) {
            $data->{$curId}{$curField} .= $string;
        } else {
            $data->{$curId}{$curField} = $string;
        }
    } ,
} );

Я пробовал следующие варианты фактического разбора:

  • файл анализируется напрямую через $parser->parsefile, без параметров;
  • файл анализируется напрямую через $parser->parsefile, с опцией ProtocolEncoding;
  • файл открывается с помощью open( $handle , "<file.xml" ), затем анализируется через $parser->parse;
  • открывается с помощью open( $handle , '<:utf8' , "file.xml" ), затем анализируется с помощью $parser->parse.

Кроме того, я пробовал каждую версию с заголовком <?xml encoding="utf-8"?> в файле и без него.

Во всех случаях то, что заканчивается в $data->{$curId}{$curField}, кодируется с использованием ISO-8859-1.

Что я делаю не так?

Ответы [ 2 ]

1 голос
/ 10 августа 2011

Я знаю, что вы уже нашли ответ от Мишеля в комментариях, но я добавлю несколько вещей. С любой кодировкой вы должны строго знать, что вы принимаете и что вы отправляете. Если вам что-то нужно, не полагайтесь на окружающую среду; в конце концов кто-то другой будет использовать вашу программу и иметь испорченную среду.

Когда вы читаете файл, не используйте слой ': utf8'. Это не волнует, если октеты на самом деле UTF-8:

 open my $fh, '<:encoding(UTF-8)', $filename or ...;

Независимо от того, что вы думаете, ваш дескриптор вывода, установите его явно. Есть множество способов сделать это:

 use open ':encoding(utf8)';

Из командной строки вы можете использовать ключ -C с флагом S для создания стандартных дескрипторов UTF-8:

 perl -CS input.xml

Том Кристиансен имеет длинный список вещей, на которые нужно обратить внимание .

0 голосов
/ 19 марта 2011

Есть ли на $data->{$curId}{$curField} флаг utf8?

Если вы объедините строку с включенным флагом utf8 со строкой, у которой отключен флаг utf8, Perl преобразует ее в Unicode. Это обычный источник проблем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...