RE: [SOAP] Re: PEAR::SOAP - Nested complex types - Is it possible?
| From: | Gendron Bruno | Date: | Mon, 21 Jul 2003 21:42:10 +0000 |
| Subject: | RE: [SOAP] Re: PEAR::SOAP - Nested complex types - Is it possible? | ||
| Groups: | php.soap | ||
| Request: | Send a blank email to php-soap+get-868@lists.php.net to get a copy of this message | ||
Thanks Michele for your very complete and well-documented explanation. I'm now able to define
and use complex types like this one:
<feature>
<point>
<x>
<y>
<srid>
</point>
</feature>
But I still have problems figuring how to define complex arrays with arrayTypes other than integer
or string, like:
<featurecollection type=Array arrayType=point>
<point>
<point>
<point>
...
<featurecollection>
I know I can return such a data structure by using something like:
$point = new PointClass(10.5,15);
$arr[] =& $point->to_soap('Point');
$point = new PointClass(3.1415,0);
$arr[] =& $point->to_soap('Point');
$collection =& new SOAP_Value('featurecollection','Array',$arr);
$collection ->arrayType='point;
But how would I define such an arrayType to be used in the automatic WSDL generation?
Thanks!
--
Bruno Gendron
> -----Message d'origine-----
> De : Michele Manzato [mailto:Michele.Manzato@verona.miz.it]
> Envoyé : vendredi 11 juillet 2003 05:31
> À : soap@lists.php.net
> Objet : [SOAP] Re: PEAR::SOAP - Nested complex types - Is it possible?
>
>
> Hi,
> (I apologise for not being very short...)
>
> I bumped into kind of a similar problem. Basically, the SOAP
> service I am
> implementing sends forth and back quite complex tree-like
> structures (it's
> an address search & route planning web service: structs
> containing structs
> and arrays that, in turn, contain structs...).
>
> These types are handled quite OK by the WSDL generation
> routines (thank you
> all who did this great job) by using the "$soapclass->__typedef[]"
> associative array, e.g:
>
> $soapclass->__typedef['{urn:myWebService}CoordinatesType'] =
> array('Longitude' => 'float',
> 'Latitude' => 'float');
>
> $soapclass->__typedef['{urn:myWebService}AddressMatchType'] =
> array('Town' => 'string',
> 'Address' => 'string',
> 'Coordinates' =>
> '{urn:myWebService}CoordinatesType');
>
> ... and so on. Also, service ports (methods) are correctly
> rendered in WSDL
> as long as I define them in the
> "$soapclass->__dispatch_map[]" associative
> array, e.g.:
>
> $soapclass->__dispatch_map['findAddress'] =
> array('in' => array('address' =>
> '{urn:myWebService}AddressSearchType'),
> 'out' => array('result' => 'boolean',
> 'match' =>
> '{urn:myWebService}AddressMatchType') );
>
> So, if I may answer to Bruno, almost everything which is
> needed to generate
> arbitrarily complex WSDLs should be there (nillable items are an
> exception... see my other post).
>
> The problem comes when doing type translation, e.g. mapping
> (XML elements in
> the SOAP message) <=> (PHP class instances). AFAIK, type
> translation should
> be enabled via "$soapBaseObject->__set_type_translation()", (where
> $soapBaseObject is either the $server or the $client), that is e.g.:
>
>
> $soapBaseObject->__set_type_translation('{urn:myWebService}Add
> ressMatchType'
> , 'PhpClass_AddressMatch');
>
> $soapBaseObject->__set_type_translation('{urn:myWebService}Coo
> rdinatesType',
> 'PhpClass_Coordinates');
>
> I noted that type translation works nice XML -> PHP, but PHP
> -> XML there
> are some problems. Namely, if the findAddress function above returns:
>
> function findAddress(...) {
> ...
> $match = new PhpClass_AddressMatch;
> $match->Town = "London";
> $match->Address = "Queens Crescent, 10";
> $match->Coordinates = new PhpClass_Coordinates;
> $match->Coordinates->Longitude = 11.7654321;
> $match->Coordinates->Latitude = 45.1234567;
> return array(true, $match);
> }
>
> the body of the response SOAP message produced will be:
>
> <SOAP-ENV:Body>
> <ns4:findAddressResponse>
> <result xsi:type="xsd:boolean">true</result>
> <match xsi:type="ns4:AddressMatchType">
> <Town xsi:type="xsd:string">London</Municipality>
> <Address xsi:type="xsd:string">Queens Crescent,
> 10</Address>
> <Coordinates> [*********]
> <Longitude xsi:type="xsd:float">11.7654321</Longitude>
> <Latitude xsi:type="xsd:float">45.1234567</Latitude>
> </Coordinates>
> </match></ns4:findAddressResponse>
> </SOAP-ENV:Body>
>
> As you can see, the [*********] element misses the "xsi:type"
> specification
> (isn't it required in "Section5 encoding"?). I had a look
> into the code, and
> I expect that with anything nested deeply than the first
> level the SOAP
> serializer behaves the same. The real problem comes when the
> SOAP client
> tries to parse the response (remember that it also knows about type
> mappings): in fact it maps quite correctly the AddressMatchType to a
> PhpClass_AddressMatch, but it fails to map the Coordinates to a
> PhpClass_Coordinates since it has no knowledge of this element's type.
> Eventually a phpClass object is created instead.
>
> Ok, I know I could use SOAP_Value to force the serialization
> of the right
> type, but that's not really "automatic" type mapping.
>
> Some other feelings & experiences?
>
> Regards
> Michele
>
> --------------------------------------------------------------
> --------------
> -----------
>
>
> "Gendron Bruno" <b.gendron@umontreal.ca> ha scritto nel messaggio
>
> news:B5835E1CC5947D4F81BEAE6C6997398F8A159D@etna.sim.umontreal.ca...
>
> Hi,
>
> Supposing a web service that would return a message element of type
> FeatureCollection containing an array of elements
> (ArrayofFeatures) of type
> Feature, as defined in the WSDL snippet below:
>
> <types
> xmlns="http://schemas.xmlsoap.org/wsdl/">
> <schema xmlns="http://www.w3.org/2001/XMLSchema"
> targetNamespace="http://mynamespace.net">
> <complexType name="FeatureCollection">
> <sequence>
> <element name="count" type="xsd:int"
> <element name="features" type="ArrayOfFeatures" />
> </sequence>
> </complexType>
> <complexType name="ArrayOfFeatures">
> <complexContent>
> <restriction base="SOAP-ENC:arrayType">
> <attribute ref="SOAP-ENC:arrayType" arrayType="Feature[]" />
> </restriction>
> </complexContent>
> </complexType>
> <complexType name="Feature">
> <sequence>
> <element name="distance" type="xsd:float" />
> <element name="x" type="xsd:float" />
> <element name="y" type="xsd:float" />
> </sequence>
> </complexType>
> </schema>
> </types>
>
> Is the PEAR::SOAP implementation capable of handling such
> complex types? If
> not, I would have to rely on some other SOAP implementation...
>
> If so, how would you proceed to define such element types in
> the server in
> order to use PEAR::SOAP WSDL generation capabilities (I have
> looked carefuly
> through the examples and documentation, without being able to
> figure out)?
> Also, how would you create such a FeatureCollection element
> in order to be
> able to send it back from the PHP server? I understand the process for
> simple types (return $somestring;) of "simple" complex types,
> but for nested
> complex types?
>
> Many thanks...
>
> ----
> Bruno Gendron
> Conseiller scientifique - Spécialiste en géomatique / Advisor - GIS
> Specialist
> Chaire de recherche du Canada en études asiatiques / Canada
> Chair of Asian
> Research
> Université de Montréal
> 3477, rue Jean-Brillant, bureau 530-26
> C.P. 6128, Succ. Centre-ville
> Montréal, QC, Canada, H3C 3J7
> Tél : +1 514-343-5768
> Fax (CETASE) : +1 514-343-7716
> Web : http://www.caac.umontreal.ca
>
>
>
> --
> PHP Soap Mailing List (http://www.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php
>