Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

parse xml and store data in array of hashesh

by osprofi (Initiate)
on Jul 22, 2011 at 04:50 UTC ( [id://916054]=perlquestion: print w/replies, xml ) Need Help??

osprofi has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I am trying to extract xml data with the xml::parser module and to store them into an array of hashes for further processing - tag extraction works fine, but storing the tag values into the array of hashes is the issue.

May be you can assist me here and what I am doing wrong:

xml data file:

<Catalog> <Category> <Name>Arts &amp; Entertainment</Name> <Site> <Id>...</Id> <Title>...</Title> </Site> <Site> <Id>...</Id> <Title>...</Title> </Site> </Category> <Catalog>

perl prg:

$parser = XML::Parser->new(Handlers => {Start => \&start, Char => \&char, End => \&end} ); sub start{ my ($p, $elt, %atts) = @_; if ($elt eq 'Site') { %site = (); #this is the hash per one site } if ($elt eq 'Id') { $tag_id = 1; } if ($elt eq 'Title') { $tag_title = 1; } } sub char { my ($p, $str) = @_; if ($tag_id eq 1) { $id = trim($str); } if ($tag_title eq 1) { $title = trim($str); } } sub end{ my ($p, $elt) = @_; if ($tag_id eq 1 and $elt eq 'Id') { $site{ $id } = $id; $tag_id = 0; } if ($tag_title eq 1 and $elt eq 'Title') { $site{ $title } = $title; $tag_title = 0; } if ($elt eq 'Site') { push(@cb, %site); print %site . "\n"; } } # if I want to process now the @cb then no data are inside.
Thanks for assistance, Peter

Replies are listed 'Best First'.
Re: parse xml and store data in array of hashesh
by Anonymous Monk on Jul 22, 2011 at 07:04 UTC
    To build an array of hashes , you need to store, hashrefs in the array, like this
    #!/usr/bin/perl -- use strict; use warnings; my %foo = 1..2; my @bar = %foo; push @bar, \%foo; use Data::Dumper; print Dumper( \@bar ); __END__ $VAR1 = [ '1', 2, { '1' => 2 } ];

    See the \ operator takes a reference, to an array (\@array), to a hash (\%hash), to a scalar (\$scalar)

    See Tutorials: References quick reference

      Hi, thanks very much for quick repl; but even with stored hash references in sub _end; the array @cb does not have data when trying to print them Greetings, Peter
        Hi, you're welcome :)

        You made it very easy as your question was very effective (How do I post a question effectively? , How do I compose an effective node title?).

        Here is a similar approach using XML::Twig

        #!/usr/bin/perl -- #~ 2011-07-23-08:42:20+0000 by Anonymous Monk #~ perltidy -csc -otr -opr -ce -nibc -i=4 use strict; use warnings; use autodie; # dies if open/close... fail use Data::Dumper; use XML::Twig; Main( @ARGV ); exit( 0 ); sub Main { Demo(); } sub NotDemoMeaningfulName { my ($xml) = @_; my @data; my %site; my $t = XML::Twig->new( twig_handlers => { '//Site' => sub { warn $_->path; push @data, {%site} if %site; %site = (); $_->purge; # free memory }, '//Site/Id' => sub { warn $_->path; $site{Id} = $_->trimmed_text; }, '//Site/Title' => sub { warn $_->path; $site{Title} = $_->trimmed_text; }, }, ); $t->xparse($xml); $t->purge; return \@data; } ## end sub NotDemoMeaningfulName sub Demo { my $ref = NotDemoMeaningfulName( DemoData() ); print Dumper($ref); } sub DemoData { #~ http://perlmonks.com/?abspart=1;displaytype=displaycode;node_id=916 +054;part=1 my $xml = <<'__XML__'; <Catalog> <Category> <Name>Arts &amp; Entertainment</Name> <Site> <Id>01-id...</Id> <Title>01-title...</Title> </Site> <Site> <Id>02-id...</Id> <Title>02-title...</Title> </Site> </Category> </Catalog> __XML__ return $xml; } ## end sub DemoData __END__ $ perl xml.twig.916054.pl /Catalog/Category/Site/Id at xml.twig.916054.pl line 30. /Catalog/Category/Site/Title at xml.twig.916054.pl line 34. /Catalog/Category/Site at xml.twig.916054.pl line 24. /Catalog/Category/Site/Id at xml.twig.916054.pl line 30. /Catalog/Category/Site/Title at xml.twig.916054.pl line 34. /Catalog/Category/Site at xml.twig.916054.pl line 24. $VAR1 = [ { 'Id' => '01-id...', 'Title' => '01-title...' }, { 'Id' => '02-id...', 'Title' => '02-title...' } ];
Re: parse xml and store data in array of hashesh
by metaperl (Curate) on Jul 22, 2011 at 16:41 UTC
Re: parse xml and store data in array of hashesh
by Jenda (Abbot) on Jul 25, 2011 at 21:39 UTC

    XML::Parser is too low-level. Have a look at XML::Rules.

    Also evaluating a hash in string context doesn't give you the contents of the hash. It returns two numbers separated by slash whose meaning is most probably the least of your worries. Pushing a hash into an array also doesn't do what you seem to think.

    Jenda
    Enoch was right!
    Enjoy the last years of Rome.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://916054]
Approved by davido
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2024-03-29 14:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found