URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 7641
[ Назад ]

Исходное сообщение
"Perl XML"

Отправлено SMF , 14-Окт-08 06:41 
Есть XML файл, который нужно разобрать и потом разнести в базу. При попытке разобрать вылетает ошибка "Not an ARRAY reference at test.pl line 24.". Получается, что есть массив:

$data -> {body}->{operation}->[$i]->{linedoc}->[$j]->{good}

просмотр по индексу проходит без проблем, а когда пытаешься просмотреть по индексу $j возникает ошибка.
Ниже формат XML и скрипт для разбора.

$VAR1 = {
          'body' => {
                    'operation' => [
                                   {
                                     'referenceNo' => '893801-',
                                     'store' => "\x{441}\x{43a}\x{43b}6",
                                     'dateDoc' => '06.10.2008',
                                     'saleSum' => {
                                                  'sumb' => '1380',
                                                  'sumr' => '1380'
                                                },
                                     'docSum' => {
                                                 'sumb' => '1380',
                                                 'sumr' => '1380'
                                               },
                                     'firm' => "\x{447}\x{435}\x{43b}64",
                                     'linedoc' => [
                                                  {
                                                    'saleSum' => {
                                                                 'sumb' => '1296',
                                                                 'sumr' => '1296'
                                                               },
                                                    'docSum' => {
                                                                'sumb' => '1296',
                                                                'rateSLT' => '00',
                                                                'sumr' => '1296',
                                                                'rateVAT' => '00'
                                                              },
                                                    'quantity' => '72',
                                                    'place' => '0',
                                                    'unitType' => "\x{434}\x{440}\x{43e}",
                                                    'good' => '109121',
                                                    'costSum' => {
                                                                 'sumb' => '1296',
                                                                 'sumr' => '1296'
                                                               },
                                                    'wait' => '0',
                                                    'type' => "\x{442}"
                                                  },
                                                  {
                                                    'saleSum' => {
                                                                 'sumb' => '84',
                                                                 'sumr' => '84'
                                                               },
                                                    'docSum' => {
                                                                'sumb' => '84',
                                                                'rateSLT' => '00',
                                                                'sumr' => '84',
                                                                'rateVAT' => '00'
                                                              },
                                                    'quantity' => '12',
                                                    'place' => '0',
                                                    'unitType' => "\x{448}\x{442}\x{443}",
                                                    'good' => '131535',
                                                    'costSum' => {
                                                                 'sumb' => '84',
                                                                 'sumr' => '84'
                                                               },
                                                    'wait' => '0',
                                                    'type' => "\x{442}"
                                                  }
                                                ],
                                     'dateFact' => '06.10.2008',
                                     'host' => '1',
                                     'codeOperation' => 'we',
                                     'costSum' => {
                                                  'sumb' => '1380',
                                                  'sumr' => '1380'
                                                },
                                     'comment' => '@  ',
                                     'paymentCode' => '1',
                                     'valutCode' => '0'
                                   },
                                   {
                                     'referenceNo' => '891954-',
                                     'store' => "\x{441}\x{43a}\x{43b}6",
                                     'dateDoc' => '03.10.2008',
                                     'saleSum' => {
                                                  'sumb' => '19200',
                                                  'sumr' => '19200'
                                                },
                                     'docSum' => {
                                                 'sumb' => '19200',
                                                 'sumr' => '19200'
                                               },
                                     'firm' => "\x{43e}\x{440}\x{433}187",
                                     'linedoc' => {
                                                  'saleSum' => {
                                                               'sumb' => '19200',
                                                               'sumr' => '19200'
                                                             },
                                                  'docSum' => {
                                                              'sumb' => '19200',
                                                              'rateSLT' => '00',
                                                              'sumr' => '19200',
                                                              'rateVAT' => '00'
                                                            },
                                                  'quantity' => '50',
                                                  'place' => '0',
                                                  'unitType' => "\x{448}\x{442}\x{443}",
                                                  'costSum' => {},
                                                  'good' => '122442',
                                                  'comment' => "\x{432}\x{435}\x{441}  \x{43a}\x{433} \x{432} \x{43f}\x{430}\x{43b}\x{43b}\x{435}\x{442}\x{435} 48 \x{448}\x{442}",
                                                  'wait' => '0',
                                                  'type' => "\x{442}"
                                                },
                                     'dateFact' => '07.10.2008',
                                     'host' => '1',
                                     'codeOperation' => 'we',
                                     'costSum' => {},
                                     'comment' => "\x{421}\x{442}\x{440}\x{43e}\x{439}\x{43a}\x{430} \x{441}\x{43a}\x{43b}\x{430}\x{434}\x{430}.",
                                     'paymentCode' => '1',
                                     'valutCode' => '0'
                                   }


#!/usr/bin/perl
use XML::Simple;
use Data::Dumper;
use Text::Iconv;
use Encode ;

my $simple = XML::Simple->new();
my $file ='DOCUMENT.XML';
$file = encode('cp1251', $file);
my $data   = $simple->XMLin($file);

my $cv = Text::Iconv->new('utf-8','windows-1251');

my $i=0;
my $j=0;
while ($data -> {body}->{operation}->[$i]) {
        ++$i;
};
my $doc_max=$i;

foreach ($i=0;$i<$doc_max;$i++){
    $j=0;
    my  $nam    = $cv->convert($data -> {body}->{operation}->[$i]->{referenceNo});
    while ($data -> {body}->{operation}->[$i]->{linedoc}->[$j]) {
        print "$i:$j\n";
        print ($data -> {body}->{operation}->[$i]->{linedoc}->[$j]->{good});
        ++$j;
    };
};
# END


Содержание

Сообщения в этом обсуждении
"Perl XML"
Отправлено NuINu , 14-Окт-08 12:43 
>Ниже формат XML и скрипт для разбора.
>
>$VAR1 = {
>          'body' => {
>                    'operation' => [
>            
>          
>          

это не хмл формат, это какой то дамп, выложи коротенький пример хмл я.


"Perl XML"
Отправлено NuINu , 14-Окт-08 13:13 
>[оверквотинг удален]
>>
>>$VAR1 = {
>>          'body' => {
>>                    'operation' => [
>>            
>>          
>>          
>
>это не хмл формат, это какой то дамп, выложи коротенький пример хмл
>я.

к тому же неверно отфорамтированный(нету закрывающий скобок внизу)

лан, не надо, улавливай разницу:
                                    'linedoc' => [
                                                  {
                                                    'saleSum' => {
                                                                 'sumb' => '1296',
.....
                                    'linedoc' => {
                                                  'saleSum' => {
                                                               'sumb' => '19200',


"Perl XML"
Отправлено SMF , 15-Окт-08 12:13 
Да дамп, точнее его начало. Файл большой(~1M), постить его сюда не разумно. XML - это стандартная выгрузка из базы данных, используют постоянно, подгружают в 1С и т.п. Поэтому грешить на него сложно, вопрос в том как его обработать в перле.

"Perl XML"
Отправлено NuINu , 15-Окт-08 12:36 
>Да дамп, точнее его начало. Файл большой(~1M), постить его сюда не разумно.
>XML - это стандартная выгрузка из базы данных, используют постоянно, подгружают
>в 1С и т.п. Поэтому грешить на него сложно, вопрос в
>том как его обработать в перле.

мне все равно на что грешить, я показал, что ты пытаешься использовать элемент как массив, в то время как он массивом не является.(вернее является, но не всегда)


"Perl XML"
Отправлено SMF , 15-Окт-08 12:57 
Извиняюсь, понял в чем косяк. Спасибо)

"Perl XML"
Отправлено angra , 14-Окт-08 17:23 
Если хотите заниматься перлом, то забудьте про С, Pascal и подобные языки. В перле все можно сделать в разы элегантнее и эффективней. Пример прохода по вашей структуре без всяких $i и $j
foreach my $op (@{$data->{body}{operation}}) {
  #делаем что вам надо на этом уровне, например
  my $nam=$op->{referenceNo};
  foreach my $linedoc (@{$op->{linedoc}}) {
    print $linedoc->{good};
  }
)

Отмечу что от некоторых {} и -> можно было избавится, оставил для наглядности.


"Perl XML"
Отправлено SMF , 15-Окт-08 12:04 
>Если хотите заниматься перлом, то забудьте про С, Pascal и подобные языки.

Согласен, что перл отличается от всего остального, и можно писать без индексов. Но взяв ваше предложение:
>В перле все можно сделать в разы элегантнее и эффективней. Пример
>прохода по вашей структуре без всяких $i и $j
>foreach my $op (@{$data->{body}{operation}}) {
>  #делаем что вам надо на этом уровне, например
>  my $nam=$op->{referenceNo};
>  foreach my $linedoc (@{$op->{linedoc}}) {
>    print $linedoc->{good};
>  }
>)
>

и отредактировав скрипт получил следующие:
109121
131535
Not an ARRAY reference at test.pl line 27.
То есть проблема не решилась.

Как я понял он пытается перейти на следующий НЕСУЩЕСТВУЮЩИЙ элемент массива linedoc
Должен отметить, что длина массивов linedoc в каждом из элементов operation разная.