Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re: XML::Simple parsing help

by Kenosis (Priest)
on Dec 09, 2012 at 07:54 UTC ( #1007959=note: print w/ replies, xml ) Need Help??


in reply to XML::Simple parsing help

Perhaps the following will assist you:

use strict; use warnings; use XML::Simple; my $xml = <<'END'; <inventors type="array"> <inventor> <city>Aston Clinton</city> <name>Andy Barth</name> <number type="integer">1</number> <country>GB</country> <upper-name>ANDY BARTH</upper-name> </inventor> <inventor> <city>Aylesbury</city> <name>Daniele Dall'Acqua</name> <number type="integer">2</number> <country>GB</country> <upper-name>DANIELE DALL'ACQUA</upper-name> </inventor> <inventor> <city>Calne</city> <name>Nigel Drew</name> <number type="integer">3</number> <country>GB</country> <upper-name>NIGEL DREW</upper-name> </inventor> </inventors> END my $xml_to_hash = XMLin( $xml, ForceArray => 1, KeyAttr => {}, ); for my $inventor ( @{ $xml_to_hash->{inventor} } ) { if ( $inventor->{number}[0]{content} == 1 ) { while ( my ( $key, $value ) = each %{$inventor} ) { print "$key => @$value[0]\n" if $key ne 'number'; } } }

Output:

country => GB city => Aston Clinton upper-name => ANDY BARTH name => Andy Barth

If you review the Dumper output of $xml_to_hash, you'll see the dereferencing used above to get the data. Remember:

[ ] = array { } = hash


Comment on Re: XML::Simple parsing help
Select or Download Code
Re^2: XML::Simple parsing help
by bitingduck (Friar) on Dec 09, 2012 at 08:15 UTC

    Alternatively, using XML::TreeBuilder:

    use strict; use warnings; use XML::TreeBuilder; my $xml = <<'END'; <inventors type="array"> <inventor> <city>Aston Clinton</city> <name>Andy Barth</name> <number type="integer">1</number> <country>GB</country> <upper-name>ANDY BARTH</upper-name> </inventor> <inventor> <city>Aylesbury</city> <name>Daniele Dall'Acqua</name> <number type="integer">2</number> <country>GB</country> <upper-name>DANIELE DALL'ACQUA</upper-name> </inventor> <inventor> <city>Calne</city> <name>Nigel Drew</name> <number type="integer">3</number> <country>GB</country> <upper-name>NIGEL DREW</upper-name> </inventor> </inventors> END my $tree=XML::TreeBuilder->new(); $tree->parse($xml); my @inventornums=$tree->find_by_tag_name('number'); foreach my $inventornum(@inventornums){ if ($inventornum->as_text()==2){ my $parent=$inventornum->parent(); print $parent->as_XML; } }

        I always find XML::Simple to be so simple that it seems like extra work to back the structure out once it's parsed into a hash. XML::TreeBuilder is easier to wrap my head around with the descriptive method names, but still simpler than using XML::LibXML

      This is a very nice and simple solution.. I'm going to play with this and XML::Rules as suggested by Jenda, see which will work best with my application.. Thanks very much!

Re^2: XML::Simple parsing help
by jhoop (Acolyte) on Dec 09, 2012 at 16:41 UTC
    Thank you. Dereferencing this made me dizzy.

      You're most welcome!

      Your question has sparked many great solutions. Here's one option that uses Mojo::DOM to parse the XML.

      The parsing's in a subroutine, so you just send a dom object and the number, and a hash is returned with the requested data--if found:

      use Modern::Perl; use Mojo::DOM; use Data::Dumper; my $xml = <<'END'; <inventors type="array"> <inventor> <city>Aston Clinton</city> <name>Andy Barth</name> <number type="integer">1</number> <country>GB</country> <upper-name>ANDY BARTH</upper-name> </inventor> <inventor> <city>Aylesbury</city> <name>Daniele Dall'Acqua</name> <number type="integer">2</number> <country>GB</country> <upper-name>DANIELE DALL'ACQUA</upper-name> </inventor> <inventor> <city>Calne</city> <name>Nigel Drew</name> <number type="integer">3</number> <country>GB</country> <upper-name>NIGEL DREW</upper-name> </inventor> </inventors> END my $dom = Mojo::DOM->new($xml); my %record = getInventorNum($dom, 1); print Dumper \%record; sub getInventorNum { my ( $dom, $num ) = @_; my %hash; $dom->find('number')->each( sub { if ( $_->text == $num ) { for my $element ( @{ $_->parent->children } ) { next if $element->type eq 'number'; $hash{ $element->type } = $element->text; } } } ); return %hash; }

      Dumper output of %record:

      $VAR1 = { 'country' => 'GB', 'city' => 'Aston Clinton', 'upper-name' => 'ANDY BARTH', 'name' => 'Andy Barth' };

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1007959]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (15)
As of 2014-07-28 14:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (200 votes), past polls