Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

Getting deep data from SOAP::Lite Result

by Roboz (Novice)
on Oct 17, 2012 at 08:33 UTC ( #999488=perlquestion: print w/replies, xml ) Need Help??
Roboz has asked for the wisdom of the Perl Monks concerning the following question:

I have a question: How would I get data that is deep in the data structure when the higher level data is unknown? Yeah, I think an example is in order. I have XML similar to this:

<Things> <Thing> <Animal> <ThingName>Dog</ThingName> <ThingID>123</ThingID> </Animal> </Thing> <Thing> <Veg> <ThingName>Carrot</ThingName> <ThingID>42</ThingID> </Veg> </Thing> <Thing> <Mineral> <ThingName>Talc</ThingName> <ThingID>007</ThingID> </Mineral> </Thing> </Things>

BTW the formatting of this is completely out of my control. Anyway the SOAP::Lite result data structure looks like this:

$Var1 = \{ 'Thing' => [ { 'Animal' => { 'ThingName' => 'Dog', 'ThingID' => '123' } }, { 'Veg' => { 'ThingName' => 'Carrot', 'ThingID' => '42' } }, { 'Mineral' => { 'ThingName' => 'Talc', 'ThingID' => '007' } } ] };

And I'm trying to access the 'ThingName' without knowing whether it's 'Animal', 'Veg' or 'Mineral'. Is there a way to use a wildcard in the following code?

foreach my $e ( @{ $SOAPresult->{Thing} } ) { print "$e->{*wildcard here*}{ThingName}\n"; }

... or is there some other way to get there? In reality, there are many more than three different things, so trying each is not an option. Thanks for any help you great gurus can provide. I'm looking forward to when I can start answering instead of asking!

Replies are listed 'Best First'.
Re: Getting deep data from SOAP::Lite Result
by kcott (Chancellor) on Oct 17, 2012 at 09:02 UTC

    G'day Roboz,

    Firstly, the data structure you present is invalid. In the code below, I've added a closing brace to 'Mineral' => { .... Also, you show $Var1 as being a reference to a hashref: I don't know if that's correct or another typo - the following code assumes it is correct.

    This code shows how you might go about achieving what you're after. I'll leave you to make adjustments for whatever typos may exist.

    #!/usr/bin/env perl use strict; use warnings; my $SOAPresult = \{ 'Thing' => [ { 'Animal' => { 'ThingName' => 'Dog', 'ThingID' => '123' } }, { 'Veg' => { 'ThingName' => 'Carrot', 'ThingID' => '42' } }, { 'Mineral' => { 'ThingName' => 'Talc', 'ThingID' => '007' } } ] }; my $SOAPresult_deref = $$SOAPresult; my @types = qw{Animal Veg Mineral}; for my $type (@types) { foreach my $e ( @{ $SOAPresult_deref->{Thing} } ) { next unless exists $e->{$type}; print "Wildcard = $type\n"; print "$e->{$type}{ThingName}\n"; } }


    $ Wildcard = Animal Dog Wildcard = Veg Carrot Wildcard = Mineral Talc

    -- Ken

      Thanks for catching that closing bracket. I'm working on an offline system so I have to manually transcribe vs. cut-n-paste... Your assumption is correct, $Var1 is a reference. I was trying to just read the ThingName without knowing (or caring) what type it was. I used animal, veg and mineral as a stand in for a long list of specifics that I don't have access to, alas. I would rather use an XPath statement with valueof but I always get the "Can't call method "valueof" without a package or object reference..." error.

Re: Getting deep data from SOAP::Lite Result
by Anonymous Monk on Oct 17, 2012 at 08:39 UTC
    You don't need to know the name, use values, or use  ->findvalue( '//ThingName' )

      I wish this worked with my SOAP::Lite results. I get 'Can't call method "findvalue" (or "valueof") on unblessed reference...' errors.

        I wish this worked ...

        See SOAP::SOM find/match... its all the same

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://999488]
Approved by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (5)
As of 2018-04-23 00:20 GMT
Find Nodes?
    Voting Booth?