in reply to Re: Perl syntax question
in thread Syntax used by SOAP::Lite

Thanks everyone for the replies.

I think I'll stick with the 'traditional' syntax... at least until I really have this chained thing worked out in my head.

Re the second part - the bit where the perl namespace is populated... I'm still not clear on where SOAP::Lite finds what names/methods are available on the remote server.

What I'm doing is trying to talk to a Cisco Call Manager (some of you may remember my previous attempt doing it with XML::Twig which turned out to be a dead end), and I don't know what the method names are. I have a working example of what should be 'on the wire', but I don't know what method I should be calling to get SOAP::Lite to create the correct request packets.

For example, after creating a SOAP::Lite object and specifying the uri and proxy, I would expect to execute something like this:

my $response = $soap->functionname(param,param,param)->result
... but I don't know what 'functioname' is.

If it helps anyone answer my question, this is the working packet trace that I did by manually posting the request to the SOAP handler.

REQUEST

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/env +elope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:x +sd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <axl:getPhone xmlns:axl="http://www.cisco.com/AXL/1.0" xsi:sch +emaLocation="http://www.cisco.com/AXL/1.0 http://myhost/schema/axlsoa +p.xsd" sequence="1234"> <phoneName>SEP000011112222</phoneName> </axl:getPhone> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

Reply
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/en +velope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/enco +ding/"> <SOAP-ENV:Body> <axl:getPhoneResponse xmlns:axl="http://www.cisco.com/AXL/1.0" xmlns: +xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="h +ttp://www.cisco.com/AXL/1.0 http://MCSCM1/CCMApi/AXL/V1/axlsoap.xsd" +sequence="1234"> <return> <device> (loads of response data removed) </device> </return> </axl:getPhoneResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

Replies are listed 'Best First'.
Re: Syntax used by SOAP::Lite
by smeenz (Sexton) on Jun 03, 2005 at 22:50 UTC
    Actually, it will be clearer still if I show you what SOAP::Lite is actually generating:

    If I execute this:

    my $req = $soap->getPhone('phoneName' => 'SEP000000000000');

    then it sends this request to the call manager's soap handler:

    <?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:xsi="ht +tp://www.w3.org/1999/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP- +ENV="http://schemas.xmlsoap.org/soap/envelope/" xm lns:xsd="http://www.w3.org/1999/XMLSchema" SOAP-ENV:encodingStyle="htt +p://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <namesp1:getPhone xmlns:namesp1="http://www.cisco.com/AXL/1.0"> <c-gensym3 xsi:type="xsd:string">phoneName</c-gensym3> <c-gensym5 xsi:type="xsd:string">SEP000000000000</c-gensym5> </namesp1:getPhone> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

    And the call manager complains that it doesn't know what a c-gensym3 is (output from Data::Dumper)

    $VAR1 = { 'error' => { 'request' => 'getPhone', 'message' => ' Unexpected element. Found <c-gensym3>, expecting <phoneName> or <phone +Id>..', 'code' => '5005' } };
      Ah.. got it. Although it feels weird posting replies to my own question, it does stop other people wasting their time answering something I've already figured out.

      I found the answer in an old mailing list archive. To avoid variables being genericaly labelled as c-gensym#, you have to pass them through a SOAP::Data object, for example:

      my $req = $soap->getPhone( SOAP::Data->name(phoneName => 'SEP000000000000') )

      I hope this helps anyone else that may be having the same problem.

        Before you go to far (and subsequently end up banging your head against the wall, as so much of it seems to make no sense), you might want to take a look at the articles that Byrne Reese (the current SOAP::Lite maintainer) has written ... they'll save you a lot of headaches.

        http://www.majordojo.com/soaplite/

Re: Syntax used by SOAP::Lite
by jhourcle (Prior) on Jun 04, 2005 at 17:16 UTC
    I'm still not clear on where SOAP::Lite finds what names/methods are available on the remote server.

    Believe it or not -- it doesn't.

    It's up to the programmer to know what the methods are. There are structured ways of representing this information, for those people who use code generators, using WSDL (which I consider to be the bane of my existance]

    Some SOAP toolkits will return a wsdl if you attempt to GET the proxy URL with a QUERY string of 'wsdl'.... so in your example, you could try pointing a web browser at:

    http://services.soaplite.com/hibye.cgi?wsdl

    (it won't actually work, though, because SOAP::Lite doesn't support this by default, as it doesn't generate WSDL -- you're left to do that on your own)

    Now -- you're probably going to ask how autodispatch works then ... well, it just assumes that if it sees a command that it doesn't know about, then it should try the SOAP service.

      Yeah that all makes sense now that I've played around with it a bit more, as I realised I can make a call to things that clearly don't exist, and no perl error is generated.. it just quietly populates the soap fault data.

      Changing topics again, the problem I have now is more related to XML parsing. If I look at the actual packets coming back from the server, I can see that it has two occurances of '<lines>' in the data, but after parsing, only the first has made it through.

      I remember from when I was trying to decode the stuff myself using XML::Parser and XML::Twig that there were various options in there that could be used to change how things like that are decoded, but I haven't had a chance yet to see if the XML parser options are visible via the SOAP::Lite object.

      And once again, thanks to everyone for their help here.

        SOAP -- and I'm being nice here -- is a pain in the ass.

        It's even worse than dealing with HTML interoperability, because it's cumbersome to set up a range of tests for each toolkit, as it can require setting up a seperate client built from each toolkit.

        There are many, many things that can go wrong when trying to parse the results, but here are a few to start you off:

        • the SOAP::SOM object returned from a method call has a lot more detail than the value returned from $som->result(). The result() method only returns the _first_ value returned, if it was a list.
        • Look into the paramsout() and paramsall() methods to SOAP::SOM
        • You can access values via XPath using the valueof() method to SOAP::SOM.

        Look over the SOAP::Lite documentation ... and as you try more with it, look over it again. It hardly made any sense to me the first time through, over a year ago, but as I use it more, it starts making more and more sense.

        As you start working with it more, you'll find that it makes a whole lot of assumptions, that can make easy cases trivial to implement, but causes a whole lot more work when the assumptions fail ... like if '20040101' is a string, not an integer... or if you're trying to emulate a document/literal webservice as opposed to RPC/encoded.