Tags: soap
Returning Arrays in WSDL
2007/07/24 @ 18:41This week I've been working on setting up several web service for a project I'm working on for work. Because we are creating these web services from scratch we had to start by creating a WSDL file to describe the web service and it's functions.
WSDL is a type of xml document that describes the inputs and outputs from a web service. This can be done using a number of ways but in my case I'm using SOAP so I described my inputs and outputs using XML Schema.
In learning about WSDL I found a number of documents helpful. Forthought Inc.'s Uche Ogbuji always seems to write good articles and Using WSDL in SOAP applications no exception. Also, examining existing documents that are publicly available was also a big help. Such as this example Stock Quote web service. Or the Google SOAP web service definition.
Though after reading all of those, while returning base types like int or string or even custom objects was easy to define, I had a hard time figuring out how to define how to return arrays of objects (Actually, Google's WSDL shows an example of what I'm about to describe).
I originally thought that returning a list of objects would simply involve returning more than one of the object. Like if I defined this in my types section:
| <types> | |
| <xsd:complexType name='StaffList'> | |
| <xsd:element | |
| minOccurs='0' | |
| maxOccurs='unbounded' | |
| name='staffname' | |
| type='Staff'/> | |
| </xsd:complexType> | |
| <xsd:complexType name='Staff'> | |
| <xsd:all> | |
| <xsd:element | |
| minOccurs='0' | |
| maxOccurs='1' | |
| name='staffname' | |
| type='xsd:string'/> | |
| <xsd:element | |
| minOccurs='0' | |
| maxOccurs='1' | |
| name='staffposition' | |
| type='xsd:string'/> | |
| <xsd:element | |
| minOccurs='0' | |
| maxOccurs='1' | |
| name='salary' | |
| type='xsd:int'/> | |
| </xsd:all> | |
| </xsd:complexType> | |
| </types> |
for reference this is my message definition:
| <message name='GetStaffRequest'> | |
| <part name='sessionid' type='xsd:string'/> | |
| <part name='staffid' type='xsd:int'/> | |
| </message> | |
| <message name='GetStaffResponse'> | |
| <part name='Result' type='StaffList'/> | |
| </message> |
That's a perfectly fine piece of XML Schema but unfortunately web services clients and servers won't recognize it. Instead you need to put a restriction on your returned type to define the array you are returning as a http://schemas.xmlsoap.org/soap/encoding/:Array. Sounds hard but it is really just a matter of following the pattern below instead of what I did above.
| <xsd:complexType name='StaffList'> | |
| <xsd:complexContent mixed='false'> | |
| <xsd:restriction base='soapenc:Array'> | |
| <xsd:attribute wsdl:arrayType='Staff[]' ref='soapenc:arrayType' /> | |
| </xsd:restriction> | |
| </xsd:complexContent> | |
| </xsd:complexType> | |
| <xsd:complexType name='Staff'> | |
| <xsd:all> | |
| <xsd:element | |
| minOccurs='0' | |
| maxOccurs='1' | |
| name='staffname' | |
| type='xsd:string'/> | |
| <xsd:element | |
| minOccurs='0' | |
| maxOccurs='1' | |
| name='staffposition' | |
| type='xsd:string'/> | |
| <xsd:element | |
| minOccurs='0' | |
| maxOccurs='1' | |
| name='salary' | |
| type='xsd:int'/> | |
| </xsd:all> | |
| </xsd:complexType> |
The message definition doesn't need to change from above. After doing that your favorite web services client or server that supports WSDL should recognise that what you are returning is an array type properly.









