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

Esteemed monks,

I'm trying new grounds, and decided I should really start using XML. Ok, so I read XML::Simple, and it really does seem simple enough. Until I ran into the following problem:

I have the following XML:

<config> <gallery> <template>admin.tmpl</template> <directory>..</directory> </gallery> <pictures> <picture> <Mtime>1039101693</Mtime> <Size>4096</Size> <Type>File</Type> <Name>picture.jpg</Name> </picture> <picture> <Mtime>1039036371</Mtime> <Size>38633</Size> <Type>File</Type> <Name>test.jpg</Name> </picture> ...

Now say I want to find the Mtime of 'test.jpg'. In the hashref returned by XML::Simple, it would be here:

${$ref->{pictures}->{picture}}[1]->{Mtime}

(or something similar). But that means that to get the information I have to know it's position in the array. Is there a way to find that position without looping over the whole array? I could defenitly do something like this:

$xmlref = grep { $_->{Name} eq 'test.jpg' } @{$ref->{pictures}->{pic +ture}};

But that seems wasteful. Is there any other way?

Thanks!

-- Dan

Replies are listed 'Best First'.
Re: (z) Finding an XML element with XML::Simple
by mirod (Canon) on Dec 05, 2002 at 16:41 UTC

    You could get to the information more easily if instead of having the name in an element you had it in an attribute. then you could use the keyattr => Name option to have XML::Simple use the attribute as a key to a hash instead of using an array. If the attribute was name (all lower case) then you would not even have to use the option as it is one of the defaults.

    As it is I don't think you can avoid the loop.

      Actually, you don't have to put it in an attribute - it works just as well from a child element as long as you haven't used forcearray on that element name. I'd recommend calling XMLin something like this:

      my $config = XMLin($filename, keyattr => {picture => 'Name'}, forcearray => ['picture'] );

      Then you could access the required value like this:

      print $config->{pictures}->{picture}->{'test.jpg'}->{Mtime}, "\n";