XML::Simple Problem
am 16.02.2006 23:13:30 von Kodiak
I am calling a Web Service from perl and I am getting back the
XMLOutput in the form of a perl hash. I am trying to convert the
XMLOutput back into perl format back everytime I pass the perl hash to
the XMLin method it throws an error saying "read on filehandle failed.
Not a GLOD reference at ...". The $dataResult value is
HASH(0x9d81064). I am at the point where I do not know what to do and
any help you can provide is appreciated. Please look at my code for
reference. Thanks!
#!/usr/bin/perl -w
use SOAP::Lite;
use XML::Simple;
use Data::Dumper;
my $soap = SOAP::Lite
-> uri('http://xxx.com/')
-> on_action(sub {join '/', 'http://tempuri.org', $_[1]})
-> proxy('http://xxx.com/service.asmx');
my $method = SOAP::Data->name('AuthenticateUser')
-> attr({xmlns => 'http://tempuri.org/'});
my @params =
(
SOAP::Data->name(upn => 'jason.test'),
SOAP::Data->name(password => 'Password1'),
SOAP::Data->name(appGuid => 'xxx'),
SOAP::Data->name(accessKey => 'xxx'),
);
my $dataResult = $soap->call($method => @params)->result;
my $xml = new XML::Simple;
my $finalResult = $xml->XMLin($dataResult);
print Dumper($finalResult);
Re: XML::Simple Problem
am 17.02.2006 02:02:39 von unknown
Kodiak wrote:
> I am calling a Web Service from perl and I am getting back the
> XMLOutput in the form of a perl hash. I am trying to convert the
> XMLOutput back into perl format back everytime I pass the perl hash to
> the XMLin method it throws an error saying "read on filehandle failed.
> Not a GLOD reference at ...". The $dataResult value is
> HASH(0x9d81064). I am at the point where I do not know what to do and
> any help you can provide is appreciated. Please look at my code for
> reference. Thanks!
>
> #!/usr/bin/perl -w
>
> use SOAP::Lite;
> use XML::Simple;
> use Data::Dumper;
>
> my $soap = SOAP::Lite
> -> uri('http://xxx.com/')
> -> on_action(sub {join '/', 'http://tempuri.org', $_[1]})
> -> proxy('http://xxx.com/service.asmx');
>
> my $method = SOAP::Data->name('AuthenticateUser')
> -> attr({xmlns => 'http://tempuri.org/'});
>
> my @params =
> (
> SOAP::Data->name(upn => 'jason.test'),
> SOAP::Data->name(password => 'Password1'),
> SOAP::Data->name(appGuid => 'xxx'),
> SOAP::Data->name(accessKey => 'xxx'),
> );
>
> my $dataResult = $soap->call($method => @params)->result;
print Dumper ($dataResult);
>
> my $xml = new XML::Simple;
>
> my $finalResult = $xml->XMLin($dataResult);
>
> print Dumper($finalResult);
>
The XML::Simple docs say that XMLin wants a string or a file handle. On
the information you have provided $dataResult is not a string, it's a
hash reference. I would guess that XML::Simple does something like
local $/ = undef;
my $string = $ref $_[0] ? <$_[0]> : $_[0];
The first thing I would do is to see if your result is already parsed.
Hence the Dumper ($dataResult). If not, pass the string you want parsed,
not the whole hash.
Tom Wyant
Re: XML::Simple Problem
am 17.02.2006 05:00:47 von Kodiak
Hi Tom,
I am somewhat of a newbie at perl so I do nto know how to check if the
hash reference is already parsed. I would like to know how do you
convert the hash reference into useable perl variables you can
manipulate. Thanks!
Re: XML::Simple Problem
am 17.02.2006 12:52:39 von unknown
Kodiak wrote:
> Hi Tom,
>
> I am somewhat of a newbie at perl so I do nto know how to check if the
> hash reference is already parsed. I would like to know how do you
> convert the hash reference into useable perl variables you can
> manipulate. Thanks!
>
The output of
print Dumper ($dataResult);
should tell you what you're working with.
The short answer is that you can't usefully unload the hash until you
know what keys are in it. You can dump it (that's what the Dumper was
about), see what's there, and then figure out what to do with it.
For unloading the hash reference, see
$ perldoc perlreftut
(that's "Perl reference tutorial"). See also
$ perldoc perlref
Basically if you want key foo, do
$dataResult->{'foo'}
If foo turns out to be a list reference and you want element 2 of the list,
$dataResult->{'foo'}[2]
If foo turns out to be a hash reference and you want element bar,
$dataResult->{'foo'}{'bar'}
Tom Wyant
Re: XML::Simple Problem
am 17.02.2006 23:39:22 von Kodiak
Hi Tom,
That worked perfectly, but I just have one more question. I was able
to output my data using Dumper and I was wondering how use output the
value of 5th index of the 'Phones' array. The 5th index has a phone
number assigned to it but I do not know how to access the value because
of the bless command. If you could let me know how to access that
value I would appreciate it. Look at the output below! Thanks!
$VAR1 = {
'User' => {
'IsAuthenticated' => 'false',
'Phones' => [
bless( {},
'Phones' ),
bless( {},
'Phones' ),
bless( {},
'Phones' ),
bless( {},
'Phones' ),
bless( {},
'Phones' )
],
'Emails' => [
bless( {}, 'Email'
),
bless( {}, 'Email'
)
]
}
};
Re: XML::Simple Problem
am 18.02.2006 03:00:43 von unknown
Kodiak wrote:
> Hi Tom,
>
> That worked perfectly, but I just have one more question. I was able
> to output my data using Dumper and I was wondering how use output the
> value of 5th index of the 'Phones' array. The 5th index has a phone
> number assigned to it but I do not know how to access the value because
> of the bless command. If you could let me know how to access that
> value I would appreciate it. Look at the output below! Thanks!
>
> $VAR1 = {
> 'User' => {
> 'IsAuthenticated' => 'false',
> 'Phones' => [
> bless( {},
> 'Phones' ),
> bless( {},
> 'Phones' ),
> bless( {},
> 'Phones' ),
> bless( {},
> 'Phones' ),
> bless( {},
> 'Phones' )
> ],
> 'Emails' => [
> bless( {}, 'Email'
> ),
> bless( {}, 'Email'
> )
> ]
> }
> };
>
Assuming "$VAR1" is really $dataResult (Dumper doesn't know any better),
the 5th element of 'Phones' would be $dataResult->{User}{Phones}[4]. You
can get away with not quoting a hash key if it would be valid as the
name of a Perl variable. You can quote them, though, if it makes you
feel better.
Once you do this, though, it's not clear to me that you will get a phone
number right off. It looks like the 'Phones' element of the hash
contains 5 'Phone' objects, but these have no attributes set. The "bless
( {}, 'Phones')" is Data::Dumper's way of telling you about an empty
hash reference that has been blessed into the Phones class. There may be
more magic involved somewhere (like calling a method?) Or maybe
something's not kosher on the server end.
If you find it helps, SOAP::Lite will do a trace if you do
use SOAP::Lite +trace => 'all';
This gets you all the XML generated by you code, and returned from the
host. You have to read the SOAP::Trace docs to find this out; it's not
in SOAP::Lite. If you know what the XML is _supposed_ to look like, it
can be a help. You may already have done the critical thing by coding
the on_action, if (as I suspect) you're talking to a .NET server.
Just a note: you _may_ find that
on_action (sub {join '', @_})
is adequate. There's nothing wrong with forcing http://tempuri.org/ in,
but I think you will get it anyway by setting attr({xmlns=>
'http://tempuri.org/'}).
Tom Wyant