Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

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
[Lady_Aleena]: To tell him or teach him?
Discipulus anyway xp is still the best lowend game machine
[Discipulus]: both: everyting must be identical in the new v-machine
[Lady_Aleena]: So putting a nice DE or WM up on a Linux machine is not an option?
[Discipulus]: i need some converter to have directly an OVF format directly: at the moment i'm trying with vmware converter standalone
[Lady_Aleena]: I don't know what to tell you. I can barely get my Linux machine to do things I want.
[Discipulus]: if DE or WM means desktop env and win manager.. no, not an option
[Lady_Aleena]: That's what they mean, at least to me. 8)
[Discipulus]: in the first attempt i failed, with an not usable v-machine.. ;=)
[Discipulus]: but then discovered a registry trick to do before the physical2virtual migration

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (11)
As of 2017-05-22 18:40 GMT
Find Nodes?
    Voting Booth?