Re: [SOAP] Re: PEAR::SOAP - Nested complex types - Is it possible?

From: Date: Wed, 30 Jul 2003 23:05:29 +0000
Subject: Re: [SOAP] Re: PEAR::SOAP - Nested complex types - Is it possible?
References: 1  Groups: php.soap 
Request: Send a blank email to php-soap+get-891@lists.php.net to get a copy of this message
To setup your WSDL generation to handle arrays of complex types you need to add a new type: $this->__typedef['ArrayOfPoints'] = array(array('Point' -> '{urn:myWebService}Point')); This will build your WSDL to look something like this: <complexType name="Point"> <all> <element name="x" type="xsd:int"> <element name="y" type="xsd:int"> </all> </complexType> <complexType name="ArrayOfPoints"> <complexContent> <restriction base="SOAP-ENC:Array"> <attribute ref="SOAP-END:arrayType" wsdl:arrayType="tns:Point[]" /> </restriction> </complexContent> </complexType> Rob "Gendron Bruno" <b.gendron@umontreal.ca> wrote in message news:B5835E1CC5947D4F81BEAE6C6997398F012593B9@etna.sim.umontreal.ca... 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 >

« previous php.soap (#891) next »