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

3
  • 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 to help people move away from XML::Simple. Commented Mar 3, 2020 at 8:46
  • Thank you.Will keep this in mind. Commented Mar 3, 2020 at 13:37
  • 1
    Hi Grant, i checked your guide and it was very helpful. I could solve my issue using your examples. Commented Mar 17, 2020 at 18:35

2 Answers 2

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";
}
Sign up to request clarification or add additional context in comments.

3 Comments

I used Grant examples and i was able to solve the problem. I tried your solution and it didn't work. sorry for the delayed response.
The example is functional. I'm glad you got a working solution.
Thanks a ton for your inputs.
1

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

@comp_names = keys %{$tree->{setup}{func}{comp}};

3 Comments

It isn't when there's only one comp tag, which is the XML::Simple problem here.
True dat . . . .
I used XML::LibXML perl package and it worked for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.