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

SOAP::Lite server returning an array of structures

Expand Messages
  • Thomas J Pinkl
    I could use some help getting a SOAP::Lite server to return an array of structures. I m using SOAP::Lite version 0.65_6. I ve read the SOAP::Lite docs and
    Message 1 of 1 , Aug 24, 2005
    View Source
    • 0 Attachment
      I could use some help getting a SOAP::Lite server to return an array
      of structures. I'm using SOAP::Lite version 0.65_6.

      I've read the SOAP::Lite docs and I've browsed these sites:

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

      but I still cannot get it to work.

      I apologize in advance for the length of this post.


      The SOAP server has a %results hash which must be returned. %results
      will contain simple scalars and *may* contain hash refs and/or array
      refs. The arrays, in turn, may contain simple scalars or hash refs.

      Here's a Data::Dumper dump of \%results:

      $VAR1 = {
      'dataArray' => [
      {
      'state' => 'PA',
      'code' => '0123',
      'company' => 'ABC Dry Cleaning'
      },
      {
      'state' => 'PA',
      'code' => '0234',
      'company' => 'Smith Brothers Lawn Care'
      }
      ],
      'count' => '2'
      };


      And here is my soap_data() function, which takes the %results hash and
      returns an array of SOAP::Data objects. I've tried this code both
      with and without the '\' in the SOAP::Data::value() calls for the
      outer elements (ie. level0 and level1). But the resulting XML is
      not what I expect (see below).


      -- cut here --
      ##
      ## takes a hash ref, returns an array of SOAP::Data objects
      ##
      sub soap_data {
      my $self = shift;
      my $href = $_[0];
      my @resp = ();
      my $level0;

      foreach my $key (keys %{ $href }) {
      $level0 = SOAP::Data->new();
      $level0->name($key);

      if (ref($href->{$key}) eq "SCALAR") {
      $level0->value( ${ $href->{$key} } ); # dereference scalar

      } elsif (ref($href->{$key}) eq "ARRAY") {
      my $aref = $href->{$key};
      if (ref($aref->[0]) eq "HASH") { # we have an array of structures

      my $recname = $self->get_soap_tag( $key );
      my @structures = ();
      my @fields = ();
      my $level1;
      my $level2;

      foreach my $stref ( @{ $aref } ) {
      $level1 = SOAP::Data->new();
      $level1->name($recname);

      $level2 = SOAP::Data->new();
      $level2->name($recname);
      @fields = $self->soap_data($stref); # recursive call
      $level2->value( @fields );

      $level1->value( $level2 );
      push @structures, $level1;
      }
      $level0->value( @structures );
      } else {
      $level0->value( $aref ); # pass array ref as-is
      }
      } elsif (ref($href->{$key}) eq "HASH") {
      $level0->value( $self->soap_data($href->{$key}) ); # recursive call
      } else {
      $level0->value( $href->{$key} ); # simple scalar
      }
      push @resp,$level0;
      }
      return @resp;
      }
      -- cut here --


      Without the '\' in the SOAP::Data::value() calls, I get a "flat" XML
      representation:

      <soap:Body>
      <namesp2:searchResponse xmlns:namesp2="myNS">
      <state>PA</state>
      <code>0123</code>
      <company>ABC Dry Cleaning</company>
      <state>PA</state>
      <code>0234</code>
      <company>Smith Brothers Lawn Care</company>
      <count>2</count>
      </namesp2:searchResponse>
      </soap:Body>


      If I put the '\' in the SOAP::Data::value() calls for level0 and level1
      I get an odd looking (to me) XML representation where the second
      structure's fields are repeated several times and the first structure's
      fields don't appear at all.

      <soap:Body>
      <namesp2:searchResponse xmlns:namesp2="myNS">
      <dataArray soapenc:arrayType="xsd:anyType[2]" xsi:type="hbsws:dataArray">
      <data href="#ref-141205584" />
      <data href="#ref-141205584" />
      </dataArray>
      <count>2</count>
      </namesp2:searchResponse>
      <state _id="1">PA</state>
      <s-gensym7 id="ref-141205584">
      <state>PA</state>
      <code>0234</code>
      <company>Smith Brothers Lawn Care</company>
      </s-gensym7>
      <code _id="1">0234</code>
      <state _id="1">PA</state>
      <code _id="1">0234</code>
      <company _id="1">Smith Brothers Lawn Care</company>
      <company _id="1">Smith Brothers Lawn Care</company>
      </soap:Body>


      Finally, the XML representation that I'd like to see is this:

      <soap:Body>
      <namesp2:searchResponse xmlns:namesp2="myNS">
      <dataArray soapenc:arrayType="xsd:anyType[2]" xsi:type="hbsws:dataArray">
      <data>
      <state>PA</state>
      <code>0123</code>
      <company>ABC Dry Cleaning</company>
      </data>
      <data>
      <state>PA</state>
      <code>0234</code>
      <company>Smith Brothers Lawn Care</company>
      </data>
      </dataArray>
      <count>2</count>
      </namesp2:searchResponse>
      </soap:Body>


      Can anyone tell me what I'm doing wrong?

      PS. Thanks for reading this far. :-)

      --
      Thomas J. Pinkl | 738 Louis Drive
      Senior Systems Architect | Warminster, PA 18974
      Health Business Systems, Inc |
      An SXC Company |
    Your message has been successfully submitted and would be delivered to recipients shortly.