1

For the below check1.xml

<root>
  <setup name = "abc" version="1.1.1>
    <func>
       <comp name = "cba">
          <check>type</check>  
       </comp> 
    </func>
  </setup> 
</root>

i am able to extract the field content of comp using the below

my $lib = "check1.xml"; 
my $simple = XML::Simple->new();
my $tree = $simple->XMLin($lib);
print $tree->{setup}->{func}->{comp}->{name} ;

With this, i am able to print "cba" .I printed the $tree with the Dumper function to get the hash and i was able to construct the syntax to print the same.

However when i have multiple comp tags, i am having issues.

<root>
  <setup name = "abc" version="1.1.1">
    <func>
       <comp name = "cba">
          <check>type</check>  
       </comp> 
       <comp name = "cdf">
          <check>semi</check>  
       </comp> 
       <comp name = "mno">
          <check>auto</check>  
       </comp> 
       <comp name = "xyz">
          <check>manual</check>  
       </comp>     
    </func>
  </setup> 
</root>

How do i get the values here as when do i dump of the hash for this, i am not getting the same tag as i don't see any element i can access in the hash to get the info i need.

$VAR1 = {
          'setup' => {
                     'func' => {
                               'comp' => {
                                         'cdf' => {
                                                  'check' => 'semi'
                                                },
                                         'mno' => {
                                                  'check' => 'auto'
                                                },
                                         'cba' => {
                                                  'check' => 'type'
                                                },
                                         'xyz' => {
                                                  'check' => 'manual'
                                                }
                                       }
                             },
                     'name' => 'abc',
                     'version' => '1.1.1'
                   }
        };

I would like to extract the comp name values from the above hash to an array. Can someone give me some pointers here. i.e. get cdf, mno,xyz, cba...

pupil
  • 185
  • 9
  • 2
    As Grinnz says, don't use XML::Simple. I'm the author of XML::Simple and I agree it's terrible. I wrote this [guide to using XML::LibXML](http://grantm.github.io/perl-libxml-by-example/) to help people move away from XML::Simple. – Grant McLean Mar 03 '20 at 08:46
  • Thank you.Will keep this in mind. – pupil Mar 03 '20 at 13:37
  • 1
    Hi Grant, i checked your guide and it was very helpful. I could solve my issue using your examples. – pupil Mar 17 '20 at 18:35

2 Answers2

1

This is a big reason why XML::Simple is discouraged. XML simply does not map usefully to Perl data structures, so a slight difference in returned XML requires a very different Perl data structure.

Instead an XML parser like XML::LibXML or Mojo::DOM can traverse and retrieve the data in a consistent way regardless of how many items you get back. Here is how you might approach this with Mojo::DOM:

use strict;
use warnings;
use Mojo::DOM;

my $xml = <<'XML';
<root>
  <setup name = "abc" version="1.1.1">
    <func>
       <comp name = "cba">
          <check>type</check>  
       </comp> 
       <comp name = "cdf">
          <check>semi</check>  
       </comp> 
       <comp name = "mno">
          <check>auto</check>  
       </comp> 
       <comp name = "xyz">
          <check>manual</check>  
       </comp>     
    </func>
  </setup> 
</root>
XML

my $dom = Mojo::DOM->new->xml(1)->parse($xml);
my $names = $dom->find('root > setup > func > comp')->map(attr => 'name');
print "$_\n" for @$names;

# equivalent, in more steps:
my $comps = $dom->find('root > setup > func > comp');
foreach my $comp (@$comps) {
  print $comp->attr('name'), "\n";
}
Grinnz
  • 9,093
  • 11
  • 18
1

$tree->{setup}->{func}->{comp} is a hash reference where the name attributes are the keys, so

@comp_names = keys %{$tree->{setup}{func}{comp}};
mob
  • 117,087
  • 18
  • 149
  • 283