Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > XML::Simple портит строки


Автор: Pfailed 5.12.2013, 19:01
Такой тестовый скрипт

Код

use v5.10;
use strict;
use utf8;
use XML::Simple;

binmode STDOUT, ':utf8';

{
    local $/;
    my $xml = <DATA>;
    utf8::encode($xml);
    
    my $res = XMLin($xml);
    for my $city (@{$res->{Branch}}) {
        say "utf8=", utf8::is_utf8($city->{Name}), "; ", $city->{Name};
    }
}


__DATA__
<Branches><Branch Name="Санкт-Петербург" />
    <Branch Name="Москва" />
    <Branch Name="Омск" />
    <Branch Name="Новосибирск" />
    <Branch Name="Екатеринбург" />
    <Branch Name="Томск" />
    <Branch Name="Кемерово" />
    <Branch Name="Барнаул" />
    <Branch Name="Красноярск" />
    <Branch Name="Новокузнецк" />
    <Branch Name="Астрахань" />
    <Branch Name="Курган" />
    <Branch Name="Иркутск" />
    <Branch Name="Челябинск" />
    <Branch Name="Астана" />
    <Branch Name="Тюмень" />
    <Branch Name="Нижневартовск" />
    <Branch Name="Ростов-на-Дону" />
    <Branch Name="Одесса" />
    <Branch Name="Пермь" />
    <Branch Name="Казань" />
    <Branch Name="Уфа" />
    <Branch Name="Самара" />
    <Branch Name="Нижний Новгород" />
    <Branch Name="Бийск" />
    <Branch Name="Тольятти" />
    <Branch Name="Краснодар" />
    <Branch Name="Владивосток" />
    <Branch Name="Магнитогорск" />
    <Branch Name="Горно-Алтайск" />
    <Branch Name="Набережные Челны" />
    <Branch Name="Ярославль" />
    <Branch Name="Волгоград" />
    <Branch Name="Воронеж" />
    <Branch Name="Сочи" />
    <Branch Name="Саратов" />
    <Branch Name="Рязань" />
    <Branch Name="Хабаровск" />
    <Branch Name="Алматы" />
    <Branch Name="Кострома" />
    <Branch Name="Падуя" />
    <Branch Name="Тула" />
    <Branch Name="Улан-Удэ" />
    <Branch Name="Сургут" />
    <Branch Name="Ижевск" />
    <Branch Name="Калининград" />
    <Branch Name="Пенза" />
    <Branch Name="Нижний Тагил" />
    <Branch Name="Белгород" />
    <Branch Name="Тверь" />
    <Branch Name="Оренбург" />
    <Branch Name="Благовещенск" />
    <Branch Name="Братск" />
    <Branch Name="Архангельск" />
    <Branch Name="Якутск" />
    <Branch Name="Чебоксары" />
    <Branch Name="Стерлитамак" />
    <Branch Name="Абакан" />
    <Branch Name="Липецк" />
    <Branch Name="Ульяновск" />
    <Branch Name="Киров" />
    <Branch Name="Ставрополь" />
</Branches>


На выходе получается

Цитата

utf8=1; Санкт-Петербург
utf8=1; Москва
utf8=1; Омск
utf8=1; Новосибирск
utf8=1; Екатеринбург
utf8=1; Томск
utf8=1; Кемерово
utf8=1; Барнаул
utf8=1; Красноярск
utf8=1; Новокузнецк
utf8=1; Астрахань
utf8=1; Курган
utf8=1; Иркутск
utf8=1; Челябинск
utf8=1; Астана
utf8=1; Тюмень
utf8=1; Нижневартовск
utf8=1; Ростов-на-Дону
utf8=1; Одесса
utf8=1; Пермь
utf8=1; Казань
utf8=1; Уфа
utf8=1; Самара
utf8=1; Нижний Новгород
utf8=1; Бийск
utf8=1; Тольятти
utf8=1; Краснодар
utf8=1; Владивосток
utf8=1; Магнитогорск
utf8=1; Горно-Алтайск
utf8=1; Набережные Челны
utf8=1; Ярославль
utf8=1; Волгоград
utf8=1; Воронеж
utf8=1; Сочи
utf8=1; Саратов
utf8=1; Рязань
utf8=1; Хабаровск
utf8=1; Алматы
utf8=1; Кострома
utf8=1; Падуя
utf8=1; Тула
utf8=1; Улан-Удэ
utf8=1; Сургут
utf8=1; Ижевск
utf8=1; Калининград
utf8=1; Пенза
utf8=1; Нижний Тагил
utf8=1; Белгород
utf8=1; Тверь
utf8=1; Оренбург
utf8=1; Благовещенск
utf8=1; Братск
utf8=1; Архангельск
utf8=1; Якутск
utf8=1; Чебоксары
utf8=1; Ð¡ÑеÑлиÑамак
utf8=1; Ðбакан
utf8=1; Ð¸Ð¿ÐµÑк
utf8=1; Ð£Ð»ÑÑновÑк
utf8=1; ÐиÑов
utf8=1; Ð¡ÑавÑополÑ


Т.е. последние 6 строк выводятся некорректно, хотя функция is_utf8() сообщает, что все строки являются utf8. 
Как такое возможно?

Автор: alezzz 5.12.2013, 20:18
Попробовал у себя, криво выводит посление 10 строк, а если удалить в начале десяток строк то все хорошо выводит. print вместо say ничего не меняет, только если убрать binmode STDOUT, ':utf8';, то все красиво выводит, но ругается Wide character in say at test.pl line 15

Автор: ginnie 5.12.2013, 21:07
У меня последний нормальный - Благовещенск. Добавил вывод дампа значения при помощи Devel::Peek, получилось:
Код

utf8=1; Благовещенск
SV = PV(0x7fe3390bc770) at 0x7fe33924ea30
  REFCNT = 1
  FLAGS = (POK,pPOK,UTF8)
  PV = 0x7fe33a31b200 "\320\221\320\273\320\260\320\263\320\276\320\262\320\265\321\211\320\265\320\275\321\201\320\272"\0
 [UTF8 "\x{411}\x{43b}\x{430}\x{433}\x{43e}\x{432}\x{435}\x{449}\x{435}\x{43d}\x{441}\x{43a}"]
  CUR = 24
  LEN = 32
utf8=1; Ð‘ратск
SV = PV(0x7fe3390bc760) at 0x7fe33924eaf0
  REFCNT = 1
  FLAGS = (POK,pPOK,UTF8)
  PV = 0x7fe33a31b980 "\303\220\302\221\303\221\302\200\303\220\302\260\303\221\302\202\303\221\302\201\303\220\302\272"\0
 [UTF8 "\x{d0}\x{91}\x{d1}\x{80}\x{d0}\x{b0}\x{d1}\x{82}\x{d1}\x{81}\x{d0}\x{ba}"]
  CUR = 24
  LEN = 32

XML::Simple портит данные. Правильное значение для Братска:
Код

PV = "\320\221\321\200\320\260\321\202\321\201\320\272"\0
 [UTF8 "\x{411}\x{440}\x{430}\x{442}\x{441}\x{43a}"]
  CUR = 12
  LEN = 16

Автор: Bulat 5.12.2013, 21:50
Код

#!/usr/bin/perl

use v5.10;
use strict;
use utf8;
use XML::Simple;
use Encode;
#binmode STDOUT, ':utf8';

use Data::Dumper;

{
  local $/;
  my $xml = <DATA>;
  utf8::encode($xml); 
    
  my $res = XMLin($xml);
  say Dumper $res;
  for my $city (@{$res->{Branch}}) {
    #say "utf8=", utf8::is_utf8($city->{Name}), "; ", $city->{Name};
  }
}

__DATA__
<Branches>
<Branch Name="Санкт-Петербург" />
<Branch Name="Москва" />
<Branch Name="Омск" />
<Branch Name="Новосибирск" />
<Branch Name="Екатеринбург" />
<Branch Name="Томск" />
<Branch Name="Кемерово" />
<Branch Name="Барнаул" />
<Branch Name="Красноярск" />
<Branch Name="Новокузнецк" />
<Branch Name="Астрахань" />
<Branch Name="Курган" />
<Branch Name="Иркутск" />
<Branch Name="Челябинск" />
<Branch Name="Астана" />
<Branch Name="Тюмень" />
<Branch Name="Нижневартовск" />
<Branch Name="Ростов-на-Дону" />
<Branch Name="Одесса" />
<Branch Name="Пермь" />
<Branch Name="Казань" />
<Branch Name="Уфа" />
<Branch Name="Самара" />
<Branch Name="Нижний Новгород" />
<Branch Name="Бийск" />
<Branch Name="Тольятти" />
<Branch Name="Краснодар" />
<Branch Name="Владивосток" />
<Branch Name="Магнитогорск" />
<Branch Name="Горно-Алтайск" />
<Branch Name="Набережные Челны" />
<Branch Name="Ярославль" />
<Branch Name="Волгоград" />
<Branch Name="Воронеж" />
<Branch Name="Сочи" />
<Branch Name="Саратов" />
<Branch Name="Рязань" />
<Branch Name="Хабаровск" />
<Branch Name="Алматы" />
<Branch Name="Кострома" />
<Branch Name="Падуя" />
<Branch Name="Тула" />
<Branch Name="Улан-Удэ" />
<Branch Name="Сургут" />
<Branch Name="Ижевск" />
<Branch Name="Калининград" />
<Branch Name="Пенза" />
<Branch Name="Нижний Тагил" />
<Branch Name="Белгород" />
<Branch Name="Тверь" />
<Branch Name="Оренбург" />
<Branch Name="Благовещенск" />
<Branch Name="Братск" />
<Branch Name="Архангельск" />
<Branch Name="Якутск" />
<Branch Name="Чебоксары" />
<Branch Name="Стерлитамак" />
<Branch Name="Абакан" />
<Branch Name="Липецк" />
<Branch Name="Ульяновск" />
<Branch Name="Киров" />
<Branch Name="Ставрополь" />
</Branches>


Код

$VAR1 = {
          'Branch' => [
                      {
                        'Name' => "\x{421}\x{430}\x{43d}\x{43a}\x{442}-\x{41f}\x{435}\x{442}\x{435}\x{440}\x{431}\x{443}\x{440}\x{433}"
                      },
                      {
                        'Name' => "\x{41c}\x{43e}\x{441}\x{43a}\x{432}\x{430}"
                      },
                      {
                        'Name' => "\x{41e}\x{43c}\x{441}\x{43a}"
                      },
                      {
                        'Name' => "\x{41d}\x{43e}\x{432}\x{43e}\x{441}\x{438}\x{431}\x{438}\x{440}\x{441}\x{43a}"
                      },
                      {
                        'Name' => "\x{415}\x{43a}\x{430}\x{442}\x{435}\x{440}\x{438}\x{43d}\x{431}\x{443}\x{440}\x{433}"
                      },
                      {
                        'Name' => "\x{422}\x{43e}\x{43c}\x{441}\x{43a}"
                      },
                      {
                        'Name' => "\x{41a}\x{435}\x{43c}\x{435}\x{440}\x{43e}\x{432}\x{43e}"
                      },
                      {
                        'Name' => "\x{411}\x{430}\x{440}\x{43d}\x{430}\x{443}\x{43b}"
                      },
                      {
                        'Name' => "\x{41a}\x{440}\x{430}\x{441}\x{43d}\x{43e}\x{44f}\x{440}\x{441}\x{43a}"
                      },
                      {
                        'Name' => "\x{41d}\x{43e}\x{432}\x{43e}\x{43a}\x{443}\x{437}\x{43d}\x{435}\x{446}\x{43a}"
                      },
                      {
                        'Name' => "\x{410}\x{441}\x{442}\x{440}\x{430}\x{445}\x{430}\x{43d}\x{44c}"
                      },
                      {
                        'Name' => "\x{41a}\x{443}\x{440}\x{433}\x{430}\x{43d}"
                      },
                      {
                        'Name' => "\x{418}\x{440}\x{43a}\x{443}\x{442}\x{441}\x{43a}"
                      },
                      {
                        'Name' => "\x{427}\x{435}\x{43b}\x{44f}\x{431}\x{438}\x{43d}\x{441}\x{43a}"
                      },
                      {
                        'Name' => "\x{410}\x{441}\x{442}\x{430}\x{43d}\x{430}"
                      },
                      {
                        'Name' => "\x{422}\x{44e}\x{43c}\x{435}\x{43d}\x{44c}"
                      },
                      {
                        'Name' => "\x{41d}\x{438}\x{436}\x{43d}\x{435}\x{432}\x{430}\x{440}\x{442}\x{43e}\x{432}\x{441}\x{43a}"
                      },
                      {
                        'Name' => "\x{420}\x{43e}\x{441}\x{442}\x{43e}\x{432}-\x{43d}\x{430}-\x{414}\x{43e}\x{43d}\x{443}"
                      },
                      {
                        'Name' => "\x{41e}\x{434}\x{435}\x{441}\x{441}\x{430}"
                      },
                      {
                        'Name' => "\x{41f}\x{435}\x{440}\x{43c}\x{44c}"
                      },
                      {
                        'Name' => "\x{41a}\x{430}\x{437}\x{430}\x{43d}\x{44c}"
                      },
                      {
                        'Name' => "\x{423}\x{444}\x{430}"
                      },
                      {
                        'Name' => "\x{421}\x{430}\x{43c}\x{430}\x{440}\x{430}"
                      },
                      {
                        'Name' => "\x{41d}\x{438}\x{436}\x{43d}\x{438}\x{439} \x{41d}\x{43e}\x{432}\x{433}\x{43e}\x{440}\x{43e}\x{434}"
                      },
                      {
                        'Name' => "\x{411}\x{438}\x{439}\x{441}\x{43a}"
                      },
                      {
                        'Name' => "\x{422}\x{43e}\x{43b}\x{44c}\x{44f}\x{442}\x{442}\x{438}"
                      },
                      {
                        'Name' => "\x{41a}\x{440}\x{430}\x{441}\x{43d}\x{43e}\x{434}\x{430}\x{440}"
                      },
                      {
                        'Name' => "\x{412}\x{43b}\x{430}\x{434}\x{438}\x{432}\x{43e}\x{441}\x{442}\x{43e}\x{43a}"
                      },
                      {
                        'Name' => "\x{41c}\x{430}\x{433}\x{43d}\x{438}\x{442}\x{43e}\x{433}\x{43e}\x{440}\x{441}\x{43a}"
                      },
                      {
                        'Name' => "\x{413}\x{43e}\x{440}\x{43d}\x{43e}-\x{410}\x{43b}\x{442}\x{430}\x{439}\x{441}\x{43a}"
                      },
                      {
                        'Name' => "\x{41d}\x{430}\x{431}\x{435}\x{440}\x{435}\x{436}\x{43d}\x{44b}\x{435} \x{427}\x{435}\x{43b}\x{43d}\x{44b}"
                      },
                      {
                        'Name' => "\x{42f}\x{440}\x{43e}\x{441}\x{43b}\x{430}\x{432}\x{43b}\x{44c}"
                      },
                      {
                        'Name' => "\x{412}\x{43e}\x{43b}\x{433}\x{43e}\x{433}\x{440}\x{430}\x{434}"
                      },
                      {
                        'Name' => "\x{412}\x{43e}\x{440}\x{43e}\x{43d}\x{435}\x{436}"
                      },
                      {
                        'Name' => "\x{421}\x{43e}\x{447}\x{438}"
                      },
                      {
                        'Name' => "\x{421}\x{430}\x{440}\x{430}\x{442}\x{43e}\x{432}"
                      },
                      {
                        'Name' => "\x{420}\x{44f}\x{437}\x{430}\x{43d}\x{44c}"
                      },
                      {
                        'Name' => "\x{425}\x{430}\x{431}\x{430}\x{440}\x{43e}\x{432}\x{441}\x{43a}"
                      },
                      {
                        'Name' => "\x{410}\x{43b}\x{43c}\x{430}\x{442}\x{44b}"
                      },
                      {
                        'Name' => "\x{41a}\x{43e}\x{441}\x{442}\x{440}\x{43e}\x{43c}\x{430}"
                      },
                      {
                        'Name' => "\x{41f}\x{430}\x{434}\x{443}\x{44f}"
                      },
                      {
                        'Name' => "\x{422}\x{443}\x{43b}\x{430}"
                      },
                      {
                        'Name' => "\x{423}\x{43b}\x{430}\x{43d}-\x{423}\x{434}\x{44d}"
                      },
                      {
                        'Name' => "\x{421}\x{443}\x{440}\x{433}\x{443}\x{442}"
                      },
                      {
                        'Name' => "\x{418}\x{436}\x{435}\x{432}\x{441}\x{43a}"
                      },
                      {
                        'Name' => "\x{41a}\x{430}\x{43b}\x{438}\x{43d}\x{438}\x{43d}\x{433}\x{440}\x{430}\x{434}"
                      },
                      {
                        'Name' => "\x{41f}\x{435}\x{43d}\x{437}\x{430}"
                      },
                      {
                        'Name' => "\x{41d}\x{438}\x{436}\x{43d}\x{438}\x{439} \x{422}\x{430}\x{433}\x{438}\x{43b}"
                      },
                      {
                        'Name' => "\x{411}\x{435}\x{43b}\x{433}\x{43e}\x{440}\x{43e}\x{434}"
                      },
                      {
                        'Name' => "\x{422}\x{432}\x{435}\x{440}\x{44c}"
                      },
                      {
                        'Name' => "\x{41e}\x{440}\x{435}\x{43d}\x{431}\x{443}\x{440}\x{433}"
                      },
                      {
                        'Name' => "\x{411}\x{43b}\x{430}\x{433}\x{43e}\x{432}\x{435}\x{449}\x{435}\x{43d}\x{441}\x{43a}"
                      },
                      {
                        'Name' => "\x{411}\x{440}\x{430}\x{442}\x{441}\x{43a}"
                      },
                      {
                        'Name' => "\x{410}\x{440}\x{445}\x{430}\x{43d}\x{433}\x{435}\x{43b}\x{44c}\x{441}\x{43a}"
                      },
                      {
                        'Name' => "\x{42f}\x{43a}\x{443}\x{442}\x{441}\x{43a}"
                      },
                      {
                        'Name' => "\x{427}\x{435}\x{431}\x{43e}\x{43a}\x{441}\x{430}\x{440}\x{44b}"
                      },
                      {
                        'Name' => "\x{421}\x{442}\x{435}\x{440}\x{43b}\x{438}\x{442}\x{430}\x{43c}\x{430}\x{43a}"
                      },
                      {
                        'Name' => "\x{410}\x{431}\x{d0}\x{b0}\x{d0}\x{ba}\x{d0}\x{b0}\x{d0}\x{bd}"
                      },
                      {
                        'Name' => "\x{d0}\x{9b}\x{d0}\x{b8}\x{d0}\x{bf}\x{d0}\x{b5}\x{d1}\x{86}\x{d0}\x{ba}"
                      },
                      {
                        'Name' => "\x{d0}\x{a3}\x{d0}\x{bb}\x{d1}\x{8c}\x{d1}\x{8f}\x{d0}\x{bd}\x{d0}\x{be}\x{d0}\x{b2}\x{d1}\x{81}\x{d0}\x{ba}"
                      },
                      {
                        'Name' => "\x{d0}\x{9a}\x{d0}\x{b8}\x{d1}\x{80}\x{d0}\x{be}\x{d0}\x{b2}"
                      },
                      {
                        'Name' => "\x{d0}\x{a1}\x{d1}\x{82}\x{d0}\x{b0}\x{d0}\x{b2}\x{d1}\x{80}\x{d0}\x{be}\x{d0}\x{bf}\x{d0}\x{be}\x{d0}\x{bb}\x{d1}\x{8c}"
                      }
                    ]
        };



'Name' => "\x{410}\x{431}\x{d0}\x{b0}\x{d0}\x{ba}\x{d0}\x{b0}\x{d0}\x{bd}"

Я думаю мысль ясна!

Если бы не эти кривости, то на перле было бы скучно писать!  smile 

Автор: Pfailed 6.12.2013, 06:06
Всем спасибо.
Видимо получается, что он как-то криво заполняет внутренний буфер (этот самый PV), но при этом помечает строку как utf-8.
Кстати, как я выяснил виноват не сам XML::Simple, а XML::SAX::PurePerl, который он использует в качестве парсера (что не удивительно судя по кол-ву неразрешенных багрепортов). Если заменить парсер на другой поддерживаемый XML::Simple, то проблема уходит.

Автор: slavenk 18.2.2014, 14:45
Здесь еще интересно https://metacpan.org/pod/XML::Simple#STATUS-OF-THIS-MODULE автора, что этот модуль для новых проектов лучше не использовать

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)