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

Hi again!
This time I'd like to read a result with multiple namespacing in it. This is a sample on how it looks:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body> <ProcessSetupResponse xmlns="http://namespace1"> <ProcessSetupResult xmlns:a="http://namespace2" xmlns:i="http://www.w3 +.org/2001/XMLSchema-instance"> <a:AuthenticatedStatus>N</a:AuthenticatedStatus> <a:AuthenticatedWith>3-D Secure</a:AuthenticatedWith> ... </ProcessSetupResult> </ProcessSetupResponse> </s:Body> </s:Envelope>

Usually I do like this:
$resultat = $soapAnswer->valueof('//ProcessSetupResponse/ProcessSetupResult/a:AuthenticatedWith');
But I guess this isn't possible in this case.


So, my question is, how do I read the "a:"-elements?
And, another question,
How can use an "offline" xml file as the result, instead of the returned webservice answer? So that I can do tests without querying the webservice each time?

Replies are listed 'Best First'.
Re: SOAP::Lite - READING Multiple namespaces
by olus (Curate) on Mar 19, 2009 at 13:05 UTC

    In the code below I took the XML you provided and added a new AuthenticatedStatus element with a different namespace for testing purposes. I'm feeding XML::XPath directly with that XML, but you can also save the response you get from the webservice and feed that file instead. Just change to my $xp = XML::XPath->new(filename => 'you_xml_file');

    use strict; use warnings; use XML::XPath; my $stream = qq{ <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body> <ProcessSetupResponse xmlns="http://namespace1"> <ProcessSetupResult xmlns:a="http://namespace2" xmlns:i="http://www.w3 +.org/2001/XMLSchema-instance"> <a:AuthenticatedStatus>N</a:AuthenticatedStatus> <i:AuthenticatedStatus>Y</i:AuthenticatedStatus> <a:AuthenticatedWith>3-D Secure</a:AuthenticatedWith> ... </ProcessSetupResult> </ProcessSetupResponse> </s:Body> </s:Envelope> }; my $xp = XML::XPath->new(xml => $stream); $xp->set_namespace('a',"http://namespace2"); $xp->set_namespace('i',"http://www.w3.org/2001/XMLSchema-instance"); print "AuthStatus\t", $xp->getNodeText('//ProcessSetupResponse/Process +SetupResult/i:AuthenticatedStatus'), "\n"; print "AuthStatus\t", $xp->getNodeText('//ProcessSetupResponse/Process +SetupResult/a:AuthenticatedStatus'), "\n";

    outputs

    AuthStatus Y AuthStatus N
      Ok, thank you! That will do the trick.
      BUT, how do I get the webservice response to a file (or a variable) in the first place?
      (The XML file used in the example is dumped via traceall...)
      Usually, I operate on the result the following way:
      my $soapAnswer = $soapHanterare->call($setup => @setup_values); my $faultstring = $soapSvar->valueof('//faultstring');

      Sorry for all the stupid questions...but, see it this way, you're helping a former windows developer to the lovely world of Perl:-)

        check $soapAnswer->result. Dump it to see what you are dealing with.

Re: SOAP::Lite - READING Multiple namespaces
by Anonymous Monk on Mar 19, 2009 at 11:00 UTC
    @resultat = $soapAnswer->valueof('//ProcessSetupResponse/ProcessSetupR +esult/a:AuthenticatedWith');
    Runnable example
      Thank you!
      Do you know about my other question?

      How can use an "offline" xml file as the result, instead of the returned webservice answer? So that I can do tests without querying the webservice each time?
        DreamT:

        Check out the t directory of the installation for numerous examples ... during testing they need to use chunks of XML, so you can use the same methods they do.

        ...roboticus
      Hi again,
      Unfortunately that didn't work, gives me an empty value.