XML Schema considerations for WSDL design in conformation with WS-I Basic Profile

A valid XML schema is not necessarily valid in a WSDL definition. Learn how design decisions in XML schema definition (XSD) can have significant impact on Web service design. We've included some sample XSDs and WSDLs and we'll briefly discuss them.

Share:

Shawn X. K. Hu (shu@xtensible.net), Solution Architect, Xtensible Solutions

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.



24 October 2006

Also available in Chinese

Introduction

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

Russian Doll

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.

Salami Slice

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.

Venetian Blind

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.

Mixed pattern

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.

Types only

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.

Conclusion

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.

Resources

Learn

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into SOA and web services on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=SOA and web services, XML
ArticleID=170277
ArticleTitle=XML Schema considerations for WSDL design in conformation with WS-I Basic Profile
publish-date=10242006