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

I have some XML that I've been parsing using XML::LibXML. I've been trying to get some data from the parsing an have been unable to sucessfully get the information.

A sample of the XML is below:

<gfx> <group name="Group1" visible="true" wallpaper="false" isReferenceOb +ject="false"> <gotoButton name="GotoDisplayButton3" display="19 UNIT STATUS"> <caption fontFamily="Arial" fontSize="9" caption="MAIN MEN +U" /> <imageSettings imageName="" alignment="middleCenter"/> </gotoButton> </group> <gotoButton name="GotoDisplayButton12" display="36 AIR_OIL SYSTEM SE +TUP_2"> <caption fontFamily="Arial" fontSize="9" caption="TO CRXW616&# +xA;AIR/OIL" /> <imageSettings imageName="" alignment="middleCenter"/> </gotoButton> </gfx>
I have a gotoButton on two levels and I've been able to get the name for each button using the following code:
#!/usr/bin/perl # use strict; use warnings; use threads; use XML::LibXML; my $parser = XML::LibXML->new(); my $doc = $parser->parse_file("file.xml"); foreach my $title ($doc->findnodes('//gotoButton')) { my $button = $title->getAttribute('name'); my $display = $title->getAttribute('display'); print "$button\t$display\n"; }

What I'm trying to do is get the above information as well as the child's caption caption from each of the groups.

Ideally, I'd like to get from the data above:

GotoDisplayButton3 19 UNIT STATUS MAIN MENU

GotoDisplayButton12 36 AIR_OIL SYSTEM SETUP_2 TO CRXW616 AIR/OIL

Are there any hints that you could give using LibXML? I've gone through the documentation and nothing is jumping out at me.

Thanks

Shawn Way

Replies are listed 'Best First'.
Re: Perl LibXML Help.
by choroba (Cardinal) on Jan 29, 2014 at 15:59 UTC
    Just use XPath to find the child element and its attribute:
    #!/usr/bin/perl use warnings; use strict; use XML::LibXML; my $parser = 'XML::LibXML'->new(); my $doc = $parser->parse_file('file.xml'); for my $title ($doc->findnodes('//gotoButton')) { my $button = $title->getAttribute('name'); my $display = $title->getAttribute('display'); my $caption = $title->findvalue('caption/@caption'); print "$button\t$display: $caption\n"; }
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      Beautiful! Worked like a charm!

      Thank you very much!

Re: Perl LibXML Help.
by simmisam (Novice) on Jan 29, 2014 at 21:20 UTC

    You can use perl's XML::Simple module, it's easy to use too

    #!/usr/bin/perl use strict; use warnings; use XML::Simple; use Data::Dumper; my $xml = new XML::Simple; my $data = $xml->XMLin("test.xml"); print Dumper $data; print "$data->{'group'}{'gotoButton'}{'name'} - "; print "$data->{'group'}{'gotoButton'}{'display'}\n"; print "$data->{'gotoButton'}{'name'} - "; print "$data->{'gotoButton'}{'display'}\n"; Output: $VAR1 = { 'gotoButton' => { 'imageSettings' => { 'imageName' => '', 'alignment' => 'middleCen +ter' }, 'caption' => { 'fontFamily' => 'Arial', 'caption' => 'TO CRXW616 AIR/OIL', 'fontSize' => '9' }, 'name' => 'GotoDisplayButton12', 'display' => '36 AIR_OIL SYSTEM SETUP_2' }, 'group' => { 'gotoButton' => { 'imageSettings' => { 'imageName' => + '', 'alignment' => + 'middleCenter' }, 'caption' => { 'fontFamily' => 'Ari +al', 'caption' => 'MAIN M +ENU', 'fontSize' => '9' }, 'name' => 'GotoDisplayButton3', 'display' => '19 UNIT STATUS' }, 'visible' => 'true', 'wallpaper' => 'false', 'name' => 'Group1', 'isReferenceObject' => 'false' } }; GotoDisplayButton3 - 19 UNIT STATUS GotoDisplayButton12 - 36 AIR_OIL SYSTEM SETUP_2

    Using dumper, you will get the data inside the xml file in perl datastructure i.e, hash of hashes or arrays from which data can be pulled out in similar manner as I have mentioned in code.

      I actually started out using this, but I was having issues with multiple levels.

      We could access both the group/gotoButton and gotoButton tags easily enough; however, I would have to code in each level individually. This is ok if the XML can only have two levels, but it is possible to further nest these variables, making it hard to predict the final depth I would need to code this.

      Thanks though!

      Shawn Way

Re: Perl LibXML Help.
by Discipulus (Canon) on Jan 30, 2014 at 10:41 UTC
    ..oops i missed this..
    You can also use XML::Twig to do what you want..

    PS i get garbage printing 'CRXW616 AIR/OIL' but ..
    use warnings; use strict; use XML::Twig; my $xml=<<'XML'; <Root> <gfx> <group name="Group1" visible="true" wallpaper="false" isReferenceOb +ject="false"> <gotoButton name="GotoDisplayButton3" display="19 UNIT STATUS"> <caption fontFamily="Arial" fontSize="9" caption="MAIN MEN +U" /> <imageSettings imageName="" alignment="middleCenter"/> </gotoButton> </group> <gotoButton name="GotoDisplayButton12" display="36 AIR_OIL SYSTEM SE +TUP_2"> <caption fontFamily="Arial" fontSize="9" caption="TO CRXW616&# +xA;AIR/OIL" /> <imageSettings imageName="" alignment="middleCenter"/> </gotoButton> </gfx> </Root> XML my $twig= new XML::Twig( pretty_print => 'indented', twig_handlers => { 'gotoButton' => sub {prin +t $_->att('name')," ",$_->att('display')," ", $_->first_child('captio +n')->att('caption'),"\n" } }, ); $twig->parse( $xml);

    hth
    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.