开发者

How to parse multi record XML file ues XML::Simple in Perl

开发者 https://www.devze.com 2023-01-02 00:03 出处:网络
My data.xml <?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> <catalog> <cd country=\"UK\">

My data.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>

my test.pl

#!/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");

   # acces开发者_如何学JAVAs XML data
   print "$data->{cd}->{country}\n";
   print "$data->{cd}->{artist}\n";
   print "$data->{cd}->{price}\n";
   print "$data->{cd}->{title}\n";

Output:

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

Comment: I googled and found the article(handle single xml record). http://www.go4expert.com/forums/showthread.php?t=812 I tested with the article code, it works quite well on my laptop.

Then I created my practice code above to try to access multiple record. but failed. How can I fix it? Thank you.


Always use strict;, always use warnings; Don't quote complex references like you're doing. You're right to use Dumper;, it should have shown you that cd was an array ref - you have to specificity which 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};


If you do print Dumper($data), you will see that the data structure does not look like you think it does:

$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'
                  }
                ]
        };

You need to access the data like so:

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


In addition to what has been said by Evan, if you're unsure if you're stuck with one or many elements, ref() can tell you what it is, and you can handle it accordingly:

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;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消