Как разобрать несколько записей XML-файла XML XML :: Simple в Perl - PullRequest
1 голос
/ 04 июня 2010

Мои данные.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
  <cd country="UK">
    <title>Hide your heart</title>
    <artist>Bonnie Tyler</artist>
    <price>10.0</price>
  </cd>
  <cd country="CHN">
    <title>Greatest Hits</title>
    <artist>Dolly Parton</artist>
    <price>9.99</price>
  </cd>
  <cd country="USA">
    <title>Hello</title>
    <artist>Say Hello</artist>
    <price>0001</price>
  </cd>
</catalog>

мой тест.пл

#!/usr/bin/perl

   # use module
   use XML::Simple;
   use Data::Dumper;

   # create object
   $xml = new XML::Simple;

   # read XML file
   $data = $xml->XMLin("data.xml");

   # access XML data
   print "$data->{cd}->{country}\n";
   print "$data->{cd}->{artist}\n";
   print "$data->{cd}->{price}\n";
   print "$data->{cd}->{title}\n";

Выход:

Not a HASH reference at D:\learning\perl\t1.pl line 16.

Комментарий: я гуглил и нашел статью (обработал одну запись xml). http://www.go4expert.com/forums/showthread.php?t=812 Я протестировал с кодом статьи, он довольно хорошо работает на моем ноутбуке.

Затем я создал свой тренировочный код выше, чтобы попытаться получить доступ к нескольким записям. но не удалось. Как я могу это исправить? Спасибо.

Ответы [ 3 ]

5 голосов
/ 04 июня 2010

Всегда use strict;, всегда use warnings; Не цитируйте сложные ссылки, как вы делаете. Вы правы на use Dumper;, он должен был показать вам, что cd был ссылкой на массив - вы должны указать, какой CD.

#!/usr/bin/perl
use strict;
use warnings;

# use module
use XML::Simple;
use Data::Dumper;

# create object
my $xml = new XML::Simple;

# read XML file
my $data = $xml->XMLin("file.xml");

# access XML data
print $data->{cd}[0]{country};
print $data->{cd}[0]{artist};
print $data->{cd}[0]{price};
print $data->{cd}[0]{title};
2 голосов
/ 05 июня 2010

В дополнение к тому, что сказал Эван, если вы не уверены, что застряли с одним или несколькими элементами, ref () может сказать вам, что это такое, и вы можете справиться соответственно:

my $data = $xml->XMLin("file.xml");

if(ref($data->{cd}) eq 'ARRAY')
{
   for my $cd (@{ $data->{cd} })
   {
      print Dumper $cd;
   }
}
else # Chances are it's a single element
{
   print Dumper $cd;
}
2 голосов
/ 04 июня 2010

Если вы сделаете print Dumper($data), вы увидите, что структура данных не выглядит так, как вы думаете:

$VAR1 = {
          'cd' => [
                  {
                    'country' => 'UK',
                    'artist' => 'Bonnie Tyler',
                    'price' => '10.0',
                    'title' => 'Hide your heart'
                  },
                  {
                    'country' => 'CHN',
                    'artist' => 'Dolly Parton',
                    'price' => '9.99',
                    'title' => 'Greatest Hits'
                  },
                  {
                    'country' => 'USA',
                    'artist' => 'Say Hello',
                    'price' => '0001',
                    'title' => 'Hello'
                  }
                ]
        };

Вам необходимо получить доступ к данным следующим образом:

print "$data->{cd}->[0]->{country}\n";
print "$data->{cd}->[0]->{artist}\n";
print "$data->{cd}->[0]->{price}\n";
print "$data->{cd}->[0]->{title}\n";
...