Nested complexTypes returning empty objects

Help
2009-12-22
2013-06-06
  • elkhunter69

    elkhunter69 - 2009-12-22

    Hello there,

    I'm trying to get NuSOAP to return an object that contains other objects, I have to believe this is trivial.  Single objects are working fine, but when I try to return an object that contains other objects, I get empty objects.  For what it's worth, I put together an example to demonstrate the issue as I've had no luck finding anyone with the same problem in a weeks worth of searching, either I'm using bunk search terms or my problem is evidently trivial enough that other folks figure it out…

    I have a soap server, soap client, class file, and unit test.  The unit test confirms that the methods in the class file are operating properly, however both my soap client and SoapUI test demonstrate that an array of return objects is returning:<br/><br/>
    -- Lions, Tigers, and Bears --<br/>
    object(stdClass)#2 (0) { }<br/>
    object(stdClass)#3 (0) { }<br/>
    object(stdClass)#4 (0) { } <br/>

    All of the files can be found at

    or they can be seen at: <br/>
    WSDL: <br/>
    Client: <br/>
    Unit Test: <br/>

    I've also included the server code below, as I suspect that's where I'm going wrong.

    Any assistance would be greatly appreciated, I'm trying to build a set of services and website as a gift for someone and am running out of time.

    Thanks in advance.<br/>
    -Brian

    <code>
            require_once('/nusoap/nusoap.php');
    require_once('class.animals.php');

    ini_set("soap.wsdl_cache_enabled", "0");

    //Register the service
    $NAMESPACE = 'http://ws.2b-studios.com/Animals';

    $server = new soap_server;
    $server->configureWSDL('Animals', $NAMESPACE);
    $server->wsdl->schemaTargetNamespace = $NAMESPACE;

    //Register the data types
    $server->wsdl->addComplexType(
    'StringArray',
    'complexType',
    'array',
    '',
    'SOAP-ENC:Array',
    array(),
    array(
    array('ref'=>'SOAP-ENC:arrayType', 'wsdl:arrayType'=>'xsd:string')
    ),
    'tns:Animal'
    );

    $server->wsdl->addComplexType(
    'Behavior',
    'complexType',
    'struct',
    'all',
    '',
    array(
    'locomotion' => array('name'=>'locomotion', 'type'=>'tns:StringArray'),
    'disposition' => array('name'=>'dataTypeKey', 'type'=>'xsd:string'),
    )
    );

    $server->wsdl->addComplexType(
    'Diet',
    'complexType',
    'struct',
    'all',
    '',
    array(
    'foods' => array('name'=>'foods', 'type'=>'tns:StringArray'),
    )
    );

    $server->wsdl->addComplexType(
    'Animal',
    'complexType',
    'struct',
    'all',
    '',
    array(
    'name' => array('name'=>'name', 'type'=>'xsd:string'),
    'genus' => array('name'=>'genus', 'type'=>'xsd:string'),
    'species' => array('name'=>'species', 'type'=>'xsd:string'),
    'behavior' => array('name'=>'behavior', 'type'=>'tns:Behavior'),
    'diet' => array('name'=>'diet', 'type'=>'tns:Diet')
    )
    );

    $server->wsdl->addComplexType(
    'Animals',
    'complexType',
    'array',
    '',
    'SOAP-ENC:Array',
    array(),
    array(
    array('ref'=>'SOAP-ENC:arrayType', 'wsdl:arrayType'=>'tns:Animal')
    ),
    'tns:Animal'
    );

    //Register the visible method
    $server->register(
        'getAnimals',
        array(),
        array('return'=>'tns:Animals'),
        $NAMESPACE);
           
    $HTTP_RAW_POST_DATA = isset($GLOBALS)
                            ? $GLOBALS : '';
    $server->service($HTTP_RAW_POST_DATA);
    exit();
    </code>

      : http://ws-2b-studios.com/animals/animals.zip
      : http://ws-2b-studios.com/animals/
      : http://ws.2b-studios.com/animals/animalsServer.php?wsdl
      : http://ws.2b-studios.com/animals/animalsClient.php
      : http://ws.2b-studios.com/animals/testAnimals.php

     
  • ronaldg

    ronaldg - 2009-12-23

    I have the exact same problem and have been working on it for a week. My code is basically identical to yours. Did you find a solution?

     
  • elkhunter69

    elkhunter69 - 2009-12-23

    Unfortunately I haven't, but will post one here if I do find a solution.  Please do the same, I'm hoping one of the guru's here have seen this issue and will reply soon.

    Thanks,
    Brian

     
  • ronaldg

    ronaldg - 2009-12-24

    I did figure out a solution.

    Here it is. Sorry about the code but it isn't pretty.

    function() {

      $tempGroupObject = array() ;
       $x = array() ;
       $x =  array( array('data'=> array('a'=>1,'b'=>2)),
                    array('data'=> array('a'=>3,'b'=>4)),
                    array('data'=> array('a'=>3,'b'=>4))) ;

       $tempGroupObject =  array( 'Pic' => $x );

      }

        return $tempGroupObject;

    }

    $server = new soap_server();
    $server->configureWSDL('userpics_wsdl', 'urn:userpics_wsdl');

    $server->wsdl->addComplexType('Picture',
            'complexType',
            'struct',
            'all',
            '',
             array( 'Pic' =>  array('name' => 'Pic',
                            'type' => 'xsd:Array'))
            ) ;

    If you call the service you get this response

    <ns1:getUserPicturesResponse xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="urn:userpics_wsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="userpics_wsdl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
      <Picture xsi:type="tns:Picture">
        <Pic SOAP-ENC:arrayType="unnamed_struct_use_soapval" xsi:type="SOAP-ENC:Array">
          <item>
            <data>
              <a xsi:type="xsd:int">1</a>
              <b xsi:type="xsd:int">2</b>
            </data>
          </item>
          <item>
            <data>
              <a xsi:type="xsd:int">3</a>
              <b xsi:type="xsd:int">4</b>
            </data>
          </item>
          <item>
            <data>
              <a xsi:type="xsd:int">3</a>
              <b xsi:type="xsd:int">4</b>
            </data>
          </item>
        </Pic>
      </Picture>
    </ns1:getUserPicturesResponse>

    Which is basically what you need I think. You can adjust it to you animals and  whatever. Since you wrote the code above you will know how to adjust it to get what you need.

    Sorry I can't change it for you… I'm out of time.
    I spent hours just figuring this out.

    Good luck

     
  • ronaldg

    ronaldg - 2009-12-24

    sorry I don't know how to post XML and have it show up in the browser.

     
  • ronaldg

    ronaldg - 2009-12-24

          <item>
            <data>
              <a xsi:type="xsd:int">1</a>
              <b xsi:type="xsd:int">2</b>
            </data>
          </item>
          <item>
            <data>
              <a xsi:type="xsd:int">3</a>
              <b xsi:type="xsd:int">4</b>
            </data>
          </item>
          <item>
            <data>
              <a xsi:type="xsd:int">3</a>
              <b xsi:type="xsd:int">4</b>
            </data>
          </item>
        </Pic>
      </Picture>

    I removed the soap around it to get the xml to show up.
    So, I think this is the XML that you need.

     
  • elkhunter69

    elkhunter69 - 2009-12-24

    Hmm, very close on the XML, definitely.  This example looks very similar to the one I made up, but I wonder if it succeeds because the return type is an array rather than an object with custom child objects (meaning, non-native objects).

    Many thanks for your post, if you happen to find out anything more I would greatly appreciate any information you come across.

    Thanks again,
    Brian

     
  • ronaldg

    ronaldg - 2009-12-24

    It does work. I am using flashdeveloper and flex API. I created a webservice and it consumes it fine and can turn the xml into a valid structure.
    Without the array it fails and the complex type also fails with subchildren fails. I believe you can duplicate what you need to do with this.

     
  • elkhunter69

    elkhunter69 - 2009-12-26

    I don't doubt that it works, I'm just suggesting that perhaps the reason it *does* work is because the contents of the array are primitive types rather than objects.  Does your example still work if you make the contents of the multi-dimensional array objects rather than ints?

     
  • ronaldg

    ronaldg - 2009-12-26

    No it doesn't. I'm sure it is a bug. Sucks
    I have also gone in a different direction since it was causing me many delays. I hope they fix it soon but since there isn't a reply I'd say we're screwed.

     
  • elkhunter69

    elkhunter69 - 2009-12-26

    Aye, doesn't look good.  I'm sure there is more than one way to skin a cat.

     
  • Vinod TK

    Vinod TK - 2010-01-19

    Brian, can you try changing the "arrayType" prameter of your "StringArray" ComplexType from "tns:Animal" to "xsd:string"

     
  • pzajdel

    pzajdel - 2010-02-15

    Hi. I'm having the exact same problem. As I need to create a WebService for a .NET application, my question is: will the code work with other lib / programming language based clients?

    @elkhunter69: did you make the animals work with simple array?

     
  • Scott Nichol

    Scott Nichol - 2010-04-27

    elkhunter69 - I looked at class.animals.php.  Unfortunately, NuSOAP currently uses get_object_vars to get the values to serialize for an instance.  To my knowledge, that function knows nothing of the getter/setter method convention.  If instead of private your data members were declared as var, the class instances should serialize correctly.

    I will have a look at whether/how easy it would be to find getter methods for values to serialize.

     
  • elkhunter69

    elkhunter69 - 2010-04-27

    Great, thanks so much for reply, and especially for all of your time and effort on the NuSOAP project.

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks