SOAP::Lite Notes

Recently I’ve been playing with the perl implementation of SOAP, called SOAP::Lite.

  • Q: There is no place in the server code that describes the tags for the response!
    • A: The article at SOAP::Data describes how to put data into a complex type for a parameter for a method- I’m not yet certain if this works for the server side:

      A common question is how to do you created nested XML elements using SOAP::Lite. The following example demonstrates how:

          SOAP::Data->name('foo' => \SOAP::Data->value(
              SOAP::Data->name('bar' => '123')));

      The above code will produce the following XML:

          <foo>
            <bar>123</bar>
          </foo>
  • Q: How do I put complex types into a SOAP::Lite?
    • A: Again from SOAP::Data,

      The following code:

          $elem1 = SOAP::Data->name('item' => 123)->type('SomeObject');
          $elem2 = SOAP::Data->name('item' => 456)->type('SomeObject');
          push(@array,$elem1);
          push(@array,$elem2);
      
          my $client = SOAP::Lite
              ->readable(1)
              ->uri($NS)
              ->proxy($HOST);
      
          $temp_elements = SOAP::Data
              ->name("CallDetails" => \SOAP::Data->value(
                    SOAP::Data->name("elem1" => 'foo'),
                    SOAP::Data->name("elem2" => 'baz'),
                    SOAP::Data->name("someArray" => \SOAP::Data->value(
                        SOAP::Data->name("someArrayItem" => @array)
                                  ->type("SomeObject"))
                             )->type("ArrayOf_SomeObject") ))
      
              ->type("SomeObject");
      
          $response = $client->someMethod($temp_elements);

      Will produce the following XML:

          <?xml version="1.0" encoding="UTF-8"?>
          <SOAP-ENV:Envelope
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
              xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
              xmlns:xsd="http://www.w3.org/2001/XMLSchema"
              xmlns:namesp2="http://namespaces.soaplite.com/perl"
              SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
            <SOAP-ENV:Body>
              <namesp1:someMethod xmlns:namesp1="urn:TemperatureService">
                <CallDetails xsi:type="namesp2:SomeObject">
                  <elem1 xsi:type="xsd:string">foo</elem1>
                  <elem2 xsi:type="xsd:string">baz</elem2>
                  <someArray xsi:type="namesp2:ArrayOf_SomeObject">
                    <item xsi:type="namesp2:SomeObject">123</bar>
                    <item xsi:type="namesp2:SomeObject">456</bar>
                  </someArray>
                </CallDetails>
              </namesp1:test>
            </SOAP-ENV:Body>
          </SOAP-ENV:Envelope>
  • Q: How do you force XML data into a response?
    • A: there is defeinitely a nicer way to do it- but the only way I found was to do it “manually” by force-feeding XML to SOAP::Data. Given the XML response
      <products>
        <product>tomatobomb</product>
        <product>fishgoo</product>
      </products>

      I used

      sub productsList {
        $xml_content = "<products>" .
                "<product>tomatobomb</product>" .
                "<product>fishgoo</product>" .
                "</products>";
        $response = SOAP::Data->type('xml' => $xml_content);
        return $response;
      }
  • Q: And how do you get THAT data out?
    • A: on the client:
      $result =  $soapclient->productsList();
        @array = $result->valueof('//products/product');
      for my $t ( @array ) {
              print "node: $t \n";
      } 
  • Q: How do I force XML from the client to hardcode a request?
    • A:
  • Q: What does the no-argument, “Hello World” SOAP::Lite client SOAP request look like?
    • A: with a method “hi()” in the namespace/service “Demo”, with no arguments:
      <?xml version="1.0" encoding="UTF-8"?>
      <SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
          xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
          xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
          xmlns:xsd="http://www.w3.org/1999/XMLSchema"
          SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
        <SOAP-ENV:Body>
          <namesp1:bye xmlns:namesp1="Demo"/>
        </SOAP-ENV:Body>
      </SOAP-ENV:Envelope>
  • Q: What does the “Hello World” SOAP::Lite server response look like?
    • A:
      <?xml version="1.0" encoding="UTF-8"?>
      <SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
        xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
        xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:xsd="http://www.w3.org/1999/XMLSchema"
        SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
        <SOAP-ENV:Body>
          <namesp1:byeResponse xmlns:namesp1="Demo">
            <s-gensym3 xsi:type="xsd:string">goodbye, cruel world</s-gensym3>
          </namesp1:byeResponse>
        </SOAP-ENV:Body>
      </SOAP-ENV:Envelope>
  • Q: In SOAP::Lite, what is “namesp1”?
    • A:
  • Q: How do I get my simple data out of a SOAP response in SOAP::Lite?
    • A:
  • Q: How do I transport arrays through SOAP::Lite?
    • A:
  • Q: How do I transport hashes through SOAP::Lite?
    • A:
#!perl -w
use  SOAP::Lite;
my $s =  SOAP::Lite
       ->  uri('http://www.PerfectXML.com/NETWebSvcs/BookService')
       -> proxy('http://www.PerfectXML.NET/WebServices/SalesRankNPrice/BookService.asmx')
       -> on_action(sub{sprintf '%s/%s', @_  })
       ;
 
my $ISBN =  SOAP::Data->name('ISBN' =>  1861005466)->type('string')->uri('http://www.PerfectXML.com/NETWebSvcs/BookService');
$result =  $s->GetAll($ISBN)->result; # hash with elements
 
print  $result->{AmazonSalesRank}, "\n";
print  $result->{AmazonPrice}, "\n";
print  $result->{BNSalesRank}, "\n";
print  $result->{BNPrice}, "\n";
$result =  $s->GetRate(
   SOAP::Data->name('fromCurr')->type(string => $FromCode),
   SOAP::Data->name('ToCurr')->type(string => $ToCode)
)->result;

More links:

http://www.majordojo.com/archives/000042.php
http://www.xav.com/perl/site/lib/SOAP/Lite.html
http://builder.com.com/5100-6389-1045078-2.html
http://users.skynet.be/pascalbotte/rcx-ws-doc/soaplite.htm
http://www.majordojo.com/soaplite/docs/SOAP/Data.html

Leave a Reply