You can create XML schemas in many ways to meet W3C XML schema specifications. However, a valid schema does not necessarily mean that it is also valid for a particular Web Service Description Language (WSDL) definition. This article describes how to construct a schema properly for a Web service design to conform with both W3C WSDL specifications (WSDL v1.1) and WS-I Basic Profile (BP v1.1).
In WSDL definition, there are two message binding styles: document and Remote Procedure Call (RPC). In the WS-I Basic Profile (BP), the message binding styles are further restricted. For example, an RPC-literal binding in its SOAP body must refer to the "type" attribute in wsdl:part (BP R2203), and a document binding must go with the "element" attribute (BP R2204). The attribute "element" refers to an XML schema element, and the attribute "type" indicates both simpleType and complexType in an XSD. In short, a
document-style message is defined based on an XML schema element, and an RPC message is defined using an XML schema type.
Furthermore, only global-level elements (BP R2206) and types can be referenced in a WSDL definition. These elements and types are immediate children of <schema> in an XSD. All non-immediate components are local and are typically nested within another schema component. A component here refers to a schema element, complexType, or simpleType.
Three main XML schema design patterns are discussed in the following sections, along with other styles:
- Russian Doll
- Salami Slice
- Venetian Blind
The Russian Doll pattern has a nested structure with only one global element, such as element "Employee" -- as seen in the following example. All other components are capsulated in the root element and localized.
Listing 1. Sample XSD in a Russian Doll pattern
<xs:element name="Employee">
<xs:complexType>
<xs:sequence>
<xs:element name="ErpPerson">
<xs:complexType mixed="false">
<xs:sequence>
<xs:element name="lastName" type="xs:string"/>
<xs:element name="firstName" type="xs:string"/>
<xs:element name="mName" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="ErpAddress">
<xs:complexType mixed="false">
<xs:sequence>
<xs:element name="streetNumber" type="xs:string"/>
<xs:element name="streetName" type="xs:string"/>
<xs:element name="suiteNumber" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="stateOrProvince" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
<xs:element name="postalCode" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
|
The element that can be referenced in a WSDL definition in this case is only the root element "Employee." The schema, therefore, can only be used to define a document-style Employee message in a WSDL. Sample WSDL <message> and <binding> are listed below with an operation called publishEmployeeService, which has an input message based on the Employee schema.
Listing 2. WSDL definition for document-style Employee message
â¦
<wsdl:message name="publishEmployeeServiceRequest">
<wsdl:part name="employee" element="typeIn:Employee">
<wsdl:documentation>publish employee data</wsdl:documentation>
</wsdl:part>
</wsdl:message>
â¦
<wsdl:binding ⦠>
<soap:binding ⦠/>
<wsdl:operation name="publishEmployeeService">
<soap:operation style="document"/>
<wsdl:input name="employee">
<soap:body use="literal"/>
</wsdl:input>
â¦
</wsdl:operation>
</wsdl:binding>
|
Note that the wsdl:input "name" attribute in the wsdl:binding section has the same value of "name" attribute in wsdl:message, which refers to the Employee element. The typeIn is a prefix of the input schema targetNamespace and Employee is the root element of the schema.
The Russian Doll pattern provides the least extensible schema structure. In the example listed above, all the components except the root element are localized and not reusable. This schema fits into a document-style WSDL but is not well suited for RPC style since there is no global level type defined. Again, a "type" is what WS-I BP restricts for an RPC binding style.
In addition, the schema can't be used for cases in which extended elements may be required in a WSDL, such as using schema element ErpAddress for message definition. The ErpAddress is an element in the XML schema but not at the global level.
The Salami Slice pattern, as the name implies, dissects an XML schema into "slices" with more global level elements. This pattern is a good fit for document-style WSDL and provides more flexibility than the Russian Doll style. The following schema contains the same Employee information listed in the Russian Doll pattern but is presented differently.
Listing 3. Sample XSD in a Salami Slice pattern
<xs:element name="Employee">
<xs:complexType>
<xs:sequence>
<xs:element ref="ErpPerson"/>
<xs:element ref="ErpAddress"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="ErpPerson">
<xs:complexType mixed="false">
<xs:sequence>
<xs:element name="lastName" type="xs:string"/>
<xs:element name="firstName" type="xs:string"/>
<xs:element name="mName" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="ErpAddress">
<xs:complexType mixed="false">
<xs:sequence>
<xs:element name="streetNumber" type="xs:string"/>
<xs:element name="streetName" type="xs:string"/>
<xs:element name="suiteNumber" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="stateOrProvince" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
<xs:element name="postalCode" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
|
Both ErpPerson and ErpAddress
elements can actually be further "sliced" to have more levels of element granularity but we stopped here for simplification.
Now ErpPerson and ErpAddress
become global level elements in a schema and are reusable components that can be referenced in other components such as element "Employee". Moreover, a benefit to using the Salami Slice pattern is that more elements can be referenced in a WSDL definition. For example, both ErpPerson and ErpAddress can now be used in a WSDL to define document style messages for ErpPerson and ErpAddress payload, respectively.
To summarize, the Employee schema in the Salami Slice pattern can be used to define WSDLs with:
- Document binding-style Employee message
- Document binding-style ErpPerson message
- Document binding-style ErpAddress message
Following are the corresponding WSDL messages and binding definitions for the listed above:
Listing 4. WSDL definition for document-style Employee message
â¦
<wsdl:message name="publishEmployeeServiceRequest">
<wsdl:part name="employee" element="typeIn:Employee">
<wsdl:documentation>publish employee information</wsdl:documentation>
</wsdl:part>
</wsdl:message>
â¦
<wsdl:binding ⦠>
<soap:binding ⦠/>
<wsdl:operation name="publishEmployeeService">
<soap:operation style="document"/>
<wsdl:input name="employee">
<soap:body use="literal"/>
</wsdl:input>
â¦.
</wsdl:operation>
</wsdl:binding>
|
Listing 5. WSDL definition for document-style ErpPerson message
â¦
<wsdl:message name="publishErpPersonServiceRequest">
<wsdl:part name="erpPerson" element="typeIn:ErpPerson">
<wsdl:documentation>publish employee data</wsdl:documentation>
</wsdl:part>
</wsdl:message>
â¦
<wsdl:binding ⦠>
<soap:binding ⦠/>
<wsdl:operation name="publishEmployeeService">
<soap:operation style="document"/>
<wsdl:input name="erpPerson">
<soap:body use="literal"/>
</wsdl:input>
â¦.
</wsdl:operation>
</wsdl:binding>
|
Listing 6. WSDL definition for document-style ErpAddress message
⦠<wsdl:message name="publishErpAddressServiceRequest">
<wsdl:part name="erpAddress" element="typeIn:ErpAddress">
<wsdl:documentation>publish employee address data</wsdl:documentation>
</wsdl:part>
</wsdl:message>
â¦
<wsdl:binding ⦠>
<soap:binding ⦠/>
<wsdl:operation name="publishErpAddressService">
<soap:operation style="document"/>
<wsdl:input name="erpAddress">
<soap:body use="literal"/>
</wsdl:input>
â¦
</wsdl:operation>
</wsdl:binding>
|
However, the Salami Slice schema does not fit into an RPC-style WSDL since there is no global-level type (simple type or complex type) defined.
In this pattern, all global-level components in a schema are defined as a type except the root. The Venetian Blind pattern is similar to the Russian Doll in that both use a single global element. The difference between Venetian Blind and Salami Slice pattern is that all global components (other than the root) are now defined as types, not as schema elements as in the Salami Slice pattern.
The Venetian Blind can typically work with both document and RPC binding styles. The following schema presents the same Employee information as our previous examples, but in the Venetian Blind pattern. In addition to the root element "Employee," three global-level complex types are defined below:
Listing 7. Sample XSD in Venetian Blind pattern
<xs:element name="Employee" type="EmployeeType"/>
<xs:complexType name="EmployeeType">
<xs:sequence>
<xs:element name="ErpPerson" type="ErpPersonType"/>
<xs:element name="ErpAddress" type="ErpAddressType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ErpPersonType">
<xs:sequence>
<xs:element name="lastName" type="xs:string"/>
<xs:element name="firstName" type="xs:string"/>
<xs:element name="mName" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ErpAddressType">
<xs:sequence>
<xs:element name="streetNumber" type="xs:string"/>
<xs:element name="streetName" type="xs:string"/>
<xs:element name="suiteNumber" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="stateOrProvince" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
<xs:element name="postalCode" type="xs:string"/>
</xs:sequence>
</xs:complexType>
|
This schema can be used to define both document- and RPC-style Employee messages in a WSDL since it contains both global-level elements and types. However, it does not support a document style message for ErpPerson and ErpAddress since both are only defined as "complexType." The Employee schema in Venetian Blind pattern can be used to define WSDLs with the following:
- Document binding-style Employee message
- RPC binding-style Employee message
- RPC binding-style ErpPerson message
- RPC binding-style ErpAddress message
The corresponding WSDL <message> and <binding> definitions are listed below:
Listing 8. WSDL definition for document-style Employee message
â¦
<wsdl:message name="publishEmployeeServiceRequest">
<wsdl:part name="employee" element="typeIn:Employee">
<wsdl:documentation>publish employee information</wsdl:documentation>
</wsdl:part>
</wsdl:message>
â¦
<wsdl:binding ⦠>
<soap:binding ⦠/>
<wsdl:operation name="publishEmployeeService">
<soap:operation style="document"/>
<wsdl:input name="employee">
<soap:body use="literal"/>
</wsdl:input>
â¦.
</wsdl:operation>
</wsdl:binding>
|
Listing 9. WSDL definition for RPC-style Employee message
â¦
<wsdl:message name="publishEmployeeServiceRequest">
<wsdl:part name="employee" type="typeIn:EmployeeType">
<wsdl:documentation>publish employee information</wsdl:documentation>
</wsdl:part>
</wsdl:message>
â¦
<wsdl:binding ⦠>
<soap:binding ⦠/>
<wsdl:operation name="publishEmployeeService">
<soap:operation style="rpc"/>
<wsdl:input name="employee">
<soap:body use="literal"
namespace="http://someCompany.com/soa/2006-07-01/publishEmployeeService"/>
</wsdl:input>
â¦.
</wsdl:operation>
</wsdl:binding>
|
Listing 10. WSDL definition for RPC-style ErpPerson message
â¦
<wsdl:message name="publishErpPersonServiceRequest">
<wsdl:part name="erpPerson" type="typeIn:ErpPersonType">
<wsdl:documentation>publish employee data</wsdl:documentation>
</wsdl:part>
</wsdl:message>
â¦
<wsdl:binding ⦠>
<soap:binding ⦠/>
<wsdl:operation name="publishErpPersonService">
<soap:operation style="rpc"/>
<wsdl:input name="erpPerson">
<soap:body use="literal"
namespace="http://someCompany.com/soa/2006-07-01/publishErpPersonService"/>
</wsdl:input>
â¦.
</wsdl:operation>
</wsdl:binding>
|
Listing 11. WSDL definition for RPC-style ErpAddress message
â¦
<wsdl:message name="publishErpAddressServiceRequest">
<wsdl:part name="erpAddress" type="typeIn:ErpAddressType">
<wsdl:documentation>publish employee address data</wsdl:documentation>
</wsdl:part>
</wsdl:message>
â¦
<wsdl:binding ⦠>
<soap:binding ⦠/>
<wsdl:operation name="publishErpAddressService">
<soap:operation style="rpc"/>
<wsdl:input name="erpAddress">
<soap:body use="literal"
namespace="http://someCompany.com/soa/2006-07-01/publishErpAddressService"/>
</wsdl:input>
....
</wsdl:operation>
</wsdl:binding>
|
Although both ErpPerson and ErpAddress complexType can be referenced in an RPC-style WSDL, it is not a good practice to only define them as a complexType without a corresponding schema element, because a complexType cannot be instantiated in a payload.
For example, ErpPersonType complexType in the schema provides a data type for an ErpPerson including lastName, firstName, and mName. It is intended to create an XML payload as seen below:
Listing 12. Sample ErpPerson message payload
<ErpPerson> <lastName>Smith</lastName> <firstName>John</firstName> <mName>K</mName> </ErpPerson> |
However, the Venetian Blind-style XML schema cannot be used to generate or validate such a payload due to the lack of a matching global element in the schema. To solve the problem in this case, define both element and complexType for the ErpPerson.
You don't have to completely define your schema following the three patterns listed above. The patterns can be mixed, if needed. For example, some components can be defined as elements and some as complex types only. From an XML payload perspective, one rule is that if a component needs to be instantiated in an XML payload, then it should be defined as an element. Otherwise, it can be defined as a type.
From the WSDL definition perspective, a component should be defined as an element if it is used in a document binding style. Otherwise, a schema component can be defined as a type for an RPC binding. The schema listed below meets the following requirements for WSDL definitions:
- Document binding-style Employee message
- RPC binding-style Employee message
- Document-binding style ErpPerson message
- RPC binding-style ErpPerson message
- Document-binding style ErpAddress message
Listing 13. Sample XSD in mixed pattern
<xs:element name="Employee" type="EmployeeType"/>
<xs:complexType name="EmployeeType">
<xs:sequence>
<xs:element ref="ErpAddress"/>
<xs:element ref="ErpAddress"/>
</xs:sequence>
</xs:complexType>
<xs:element name="ErpPerson" type="ErpPersonType"/>
<xs:complexType name="ErpPersonType">
<xs:sequence>
<xs:element name="lastName" type="xs:string"/>
<xs:element name="firstName" type="xs:string"/>
<xs:element name="mName" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="ErpAddress">
<xs:complexType>
<xs:sequence>
<xs:element name="streetNumber" type="xs:string"/>
<xs:element name="streetName" type="xs:string"/>
<xs:element name="suiteNumber" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="stateOrProvince" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
<xs:element name="postalCode" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
|
A mixed pattern is more flexible in terms of accessibility of XML schema elements and types used in a WSDL. It allows you to construct an XML schema by exactly following a binding style selected in your Web service.
Sometimes only global-level types are defined in an XML schema without any global element defined. This kind of schema is typically used as a base schema to encapsulate data types to be referenced in other schemas. The following is the Employee schema with only complex type defined at the global level:
Listing 14. Sample XSD with global-level complexType only
<xs:complexType name="EmployeeType">
<xs:sequence>
<xs:element name="ErpPerson" type="ErpPersonType"/>
<xs:element name="ErpAddress" type="ErpAddressType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ErpPersonType">
<xs:sequence>
<xs:element name="lastName" type="xs:string"/>
<xs:element name="firstName" type="xs:string"/>
<xs:element name="mName" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ErpAddressType">
<xs:sequence>
<xs:element name="streetNumber" type="xs:string"/>
<xs:element name="streetName" type="xs:string"/>
<xs:element name="suiteNumber" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="stateOrProvince" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
<xs:element name="postalCode" type="xs:string"/>
The corresponding WSDL <message> and <binding> definitions are listed below:on
</xs:sequence>
</xs:complexType>
|
This schema is valid for an RPC style WSDL definition according to both W3C specifications and WS-I BP and. However, a schema without global elements is not much useful for XML payload generation and validation.
In summary, a schema needs to be constructed properly when considering a Web service design. If an XML schema is intended for both document- and RPC-style Web services, it is best to include both element and type at a global level in the schema.
Learn
- Get details on WS-I Basic Profile.
- Read Should it be an Element or a Type?
- Find out When should an element or type be declared global vesus local?
- Read "Create flexible and extensible XML schemas" on developerWorks XML zone.
- Stay current with developerWorks technical events and Webcasts.
- Read the presentation, "Using XML schemas effectively in WSDL design."
Get products and technologies
- Find out more about the W3C XML schema specifications.
- Get W3C WSDL specifications .
- Read about WS-I testing tools.
Discuss
- Participate in developerWorks
blogs and get involved in the developerWorks community.
Shawn Hu is a Solution Architect with Xtensible Solutions. His expertise includes Web services design (WSDL), data analysis and modeling, and XML/XSD design. He has worked on a variety of system integration projects focusing on interface design and data flow. He holds a Ph.D. from the University of Western Ontario in Canada.
Comments (Undergoing maintenance)





