Loading ...
Sorry, an error occurred while loading the content.

TerraService revisited -- how to control serialization?

Expand Messages
  • ericpromislow
    ... Excuse all the XML in this message -- I ve tried to edit it for relevance and brevity. I m able to generate SOAP::Lite client-side wrappers for most RPC,
    Message 1 of 5 , Jul 25, 2002
    • 0 Attachment
      Last October, 2001, --- In soaplite@y..., judson@m... wrote:
      > Has anybody figured out how to get TerraService to work with
      > SOAP::Lite?
      >

      Excuse all the XML in this message -- I've tried to edit it
      for relevance and brevity. I'm able to generate SOAP::Lite
      client-side wrappers for most RPC, but some doc/lit code
      still gives me problems. Here's an example using TerraService:

      The (edited) WSDL:

      <s:complexType name="Place">
      <s:sequence>
      <s:element 0..1 name="City" type="s:string" />
      <s:element 0..1 name="State" type="s:string" />
      <s:element 0..1 name="Country" type="s:string" />
      </s:sequence>
      ...

      <s:element name="GetPlaceFacts">
      <s:complexType>
      <s:sequence>
      <s:element 1..1 name="place" type="s0:Place" />
      </s:sequence>
      </s:complexType>
      </s:element>
      ...

      <message name="GetPlaceFactsSoapIn">
      <part name="parameters" element="s0:GetPlaceFacts" />
      </message>
      ...

      <operation name="GetPlaceFacts">
      <soap:operation
      soapAction="http://terraservice.net/terraserver/GetPlaceFacts"
      style="document" />
      <input>
      <soap:body use="literal" />
      </input>
      <output>
      <soap:body use="literal" />
      </output>
      </operation>


      Here's the code I'm generating from the WSDL:


      sub ComplexType_Place {
      my ($name, $param, $ns) = @_;
      return SOAP::Data->name($name)->type('')->uri($ns)->value
      (\SOAP::Data->value(
      SOAP::Data->name('City')->type('')->uri($ns)->value($param->
      {'City'}),
      SOAP::Data->name('State')->type('')->uri($ns)->value($param->
      {'State'}),
      SOAP::Data->name('Country')->type('')->uri($ns)->value($param-
      >{'Country'})));
      }


      sub GetPlaceFacts {
      my $place = {
      City => 'Blaine',
      State => 'Washington',
      Country => 'United States',
      };

      my $endpoint = 'http://terraservice.net/TerraService.asmx';
      my $uri = 'http://terraservice.net/terraserver/';
      my $soapObj = SOAP::Lite->new (
      'xmlschema' => '2001',
      'proxy' => $endpoint,
      'uri' => $uri,
      'serializer' =>
      My::Serializer->new('xmlschema' =>'2001'),
      );
      my $wrapped_place =
      ComplexType_Place_literal('place', $place, $uri);
      $soapObj = $soapObj ->
      on_action(sub { return
      '"http://terraservice.net/terraserver/GetPlaceFacts"';});
      my $res = $soapObj->call(SOAP::Data->name('GetPlaceFacts')
      -> attr({xmlns => $uri})->value([$wrapped_place]));
      if ($res->fault) {
      print 'GetPlaceList', $res2->faultstring, "\n";
      } else {
      print Dumper $res2->result;
      }
      }


      Here's the generated envelope:

      <?xml version='1.0'?>
      <SOAP-ENV:Envelope
      xmlns:namesp2="http://namespaces.soaplite.com/perl"
      xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <SOAP-ENV:Body>
      <GetPlaceFacts
      xmlns="http://terraservice.net/terraserver/"
      SOAP-ENC:arrayType="namesp2[1]"
      xsi:type="SOAP-ENC:Array">
      <namesp1:place
      xsi:type="namesp2" <!-- ******** -->
      xmlns:namesp1="http://terraservice.net/terraserver/">
      <namesp3:City
      xmlns:namesp3="http://terraservice.net/terraserver/"
      >Blaine</namesp3:City>
      <namesp4:State
      xmlns:namesp4="http://terraservice.net/terraserver/"
      >Washington</namesp4:State>
      <namesp5:Country
      xmlns:namesp5="http://terraservice.net/terraserver/"
      >United States</namesp5:Country>
      </namesp1:place>
      </GetPlaceFacts>
      </SOAP-ENV:Body>
      </SOAP-ENV:Envelope>

      ms.net complains about this:
      <faultstring>System.Web.Services.Protocols.SoapException:
      Server was unable to read request.
      System.InvalidOperationException:
      There is an error in XML document (1, 461).
      System.InvalidOperationException:
      The specified type was not recognized: name='namesp2',
      namespace='http://terraservice.net/terraserver/',
      at place xmlns='http://terraservice.net/terraserver/'

      If I manually remove 'xsi:type="namesp2"' from the
      place tag, it works. What do I need to tell SOAP::Lite
      to prevent this?


      Thanks.
    Your message has been successfully submitted and would be delivered to recipients shortly.