3

My input xml file is:

<?xml version='1.0'?>
<warnings>
 <IDA>
  <file>filea</file>
  <path>patha</path>
 </IDA>

 <IDA>
  <file>fileaa</file>
  <path>pathaa</path>
 </IDA>

 <IDB>
  <file>fileb</file>
  <path>pathb</path>
 </IDB>

</warnings>

I am reading this file like this:

my @IDs = ("IDA", "IDB");
my $data = $xml->XMLin("xmlfile.xml");
foreach (@IDs)
{
 foreach $id (@{$data->{$_}})
 {
   print $id->{path}."\n";
 }
}

and when I run the script it gives me this error:

Not an ARRAY reference at ./waiver.pl line 18.

(line 18 is the second foreach loop)

EDIT i have duplicated IDA tag.

4
  • 2
    Have you tried perl -d mode? 'n' to line 18, then 'x' things like $_, $data->{$_}, etc. Commented Jun 1, 2012 at 20:35
  • sorry i didn't get it? could you please explain a bit? Commented Jun 1, 2012 at 20:53
  • He means using Perl debugger with -d option Commented Jun 1, 2012 at 21:18
  • 1
    Because you're using XML::Simple, the hardest XML parser to use. Commented Jun 1, 2012 at 21:27

1 Answer 1

5

{$data->{$_} is not a valid array reference because you have only one IDA tag, thus no array is built. You can use ForceArray in XMLin to force every tag to be an array even if there's only one.

my $data = $xml->XMLin("xmlfile.xml", ForceArray => 1);

EDIT: now it's giving the error with IDB tag...

Alternatively you can use ref() to check if it's an array or a hash reference:

if (ref({$data->{$_}) eq 'ARRAY')
{
    foreach $id (@{$data->{$_}})
    {
        etc...
    }
}

PS: also may I suggest using keys() function to retreive the keys of the hash instead of having them in a separate array.

Sign up to request clarification or add additional context in comments.

2 Comments

I already told you how to handle it, but here's another option.
I typically suggest everyone use ForceArray, anyway you cut it returning two distinct types of variables is a tremendous burden on the end user. This actually bothers the hell out of me in many libraries (like DBIC).

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.