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

Pasring soap call return with array of hashes, with array inside

Expand Messages
  • Weidong Wang
    Hi, I have the following kind of soap response: ... ...
    Message 1 of 3 , Oct 18, 2002
    • 0 Attachment
      Hi, I have the following kind of soap response:
       
      <s:Envelope ...>
       <s:Body>
        <Response>
          <SpaceList>
           <Space>
            <field1>...</field1>
            <field2>...</field2>
            <field3>
             <member>...</member>
             <member>...</member>
            </field3>
          </Space>
           <Space>
            <field1>...</field1>
            <field2>...</field2>
            <field3>
             <member>...</member>
            </field3>
          </Space>
         </SpaceList>
        </Response>
       </s:Body>
      </s:Envelope>
       
      in my Perl code, I return an array of Space:
       
          @Spaces = $result->valueof('//Space');
       
      and I got an array of Space, and I can iterate through to get each Space. Each Space is a hash, I can get "field1", "field2", "field3". Single item field works fine, and when a field itself is a hash, it works fine as well. But when a field contains an array of other fields (same field name, like "member" inside "field3"), I can't get all elements. I am only getting the last field.
       
      I tried:  %Hfield3 = %{$Space{'field3'}}, and $Hfield3{'member'} only gives me the last one;
      I tried: @Members = @{$Space{'field3'}->{'member'}}; and @Members only contains the last one as well.
       
      How can I get this to work?
       
      Thanks.
       
      Weidong
       
       
    • Paul Kulchenko
      Hi Weidong, I replied to the similar message just yesterday ;). Reasons: http://groups.yahoo.com/group/soaplite/message/747 1. Navigate through envelope using
      Message 2 of 3 , Oct 18, 2002
      • 0 Attachment
        Hi Weidong,

        I replied to the similar message just yesterday ;).

        Reasons: http://groups.yahoo.com/group/soaplite/message/747

        1. Navigate through envelope using match/valueof/dataof. Easy fo
        simple structures, could be painful for the complex ones.

        2. Apply patch from Eric Promislow that turns hashes into array in
        this case: http://groups.yahoo.com/group/soaplite/message/1856
        I'm not sure that's the best way to do it and I'm still thinking
        about including this or similar patch in a future version. I would
        like to hear your opinion based on available options.

        3. Use SOAP::Custom::XML::Deserializer. Most straightforward, but not
        always applicable.

        ....
        $soap->deserializer(SOAP::Custom::XML::Deserializer->new);
        my $som = $soap->foo('bar')->result;
        for my $space ($d->SpaceList->Space) {
        for my $member ($space->field3->member) {
        print $member, "\n";
        }
        }

        See example/XML/customxml.pl and UDDI::Lite for details.

        4. Use XML::DOM or similar module to navigate the XML. It's also easy
        to do. Look at the examples/getdom.pl for more details
        (My::Deserializer).

        5. Register deserializers for complex types. Require you to write the
        code for a deserializer. Require use of some semi-documented
        structures that may change in a future. Look at the
        examples/customschema.pl.

        6. Rely on XML Schema for structure information. Not implemented yet.

        7. Do something else?

        What'd be your choice for this?

        Best wishes, Paul.

        --- Weidong Wang <wwang@...> wrote:
        > Hi, I have the following kind of soap response:
        >
        > <s:Envelope ...>
        > <s:Body>
        > <Response>
        > <SpaceList>
        > <Space>
        > <field1>...</field1>
        > <field2>...</field2>
        > <field3>
        > <member>...</member>
        > <member>...</member>
        > </field3>
        > </Space>
        > <Space>
        > <field1>...</field1>
        > <field2>...</field2>
        > <field3>
        > <member>...</member>
        > </field3>
        > </Space>
        > </SpaceList>
        > </Response>
        > </s:Body>
        > </s:Envelope>
        >
        > in my Perl code, I return an array of Space:
        >
        > @Spaces = $result->valueof('//Space');
        >
        > and I got an array of Space, and I can iterate through to get each
        > Space. Each Space is a hash, I can get "field1", "field2",
        > "field3". Single item field works fine, and when a field itself is
        > a hash, it works fine as well. But when a field contains an array
        > of other fields (same field name, like "member" inside "field3"), I
        > can't get all elements. I am only getting the last field.
        >
        > I tried: %Hfield3 = %{$Space{'field3'}}, and $Hfield3{'member'}
        > only gives me the last one;
        > I tried: @Members = @{$Space{'field3'}->{'member'}}; and @Members
        > only contains the last one as well.
        >
        > How can I get this to work?
        >
        > Thanks.
        >
        > Weidong
        >
        >


        __________________________________________________
        Do you Yahoo!?
        Faith Hill - Exclusive Performances, Videos & More
        http://faith.yahoo.com
      • Weidong Wang
        ... Paul, thanks for the response. I choose to use #3, SOAP::Custom::XML::Deserializer. #1 does not work well in this case; #2 requires patching, which I
        Message 3 of 3 , Oct 18, 2002
        • 0 Attachment
          > 3. Use SOAP::Custom::XML::Deserializer. Most straightforward, but not
          > always applicable.
          >
          > ....
          > $soap->deserializer(SOAP::Custom::XML::Deserializer->new);
          > my $som = $soap->foo('bar')->result;
          > for my $space ($d->SpaceList->Space) {
          > for my $member ($space->field3->member) {
          > print $member, "\n";
          > }
          > }
          >
          > See example/XML/customxml.pl and UDDI::Lite for details.

          Paul, thanks for the response.

          I choose to use #3, SOAP::Custom::XML::Deserializer. #1 does not work well in this case; #2 requires patching, which I prefer not to do; #4 could do, except it seems to be a little more code than #3; #5 #6 seem a little more complicated.

          Anyway, #3 works for me. For those calls that can return such complex structure, I use this custom XML deserializer and build the right structure with array and return.

          Thanks again.

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