If you implement a web service tool, especially a wsdl processor, you may have already been deeply confused about how import works in WSDL . If you are a web service developer,
*When to use wsdl import vs when to use xsd import
*How it works when a wsdl imports another wsdl which has imported schemas?
*How it works when a wsdl imports another wsdl which has embedded schemas?
*How it works when one embeded schema imports another embeded schema?
Based on clarifications provided by WS-I BP ()and current thinking in W3C WSDL2.0 work (), this note hopefully provides answers to these common questions. It assumes you have a good knowledge of wsdl and xml schema.
When to use wsdl import vs. when to use xsd import?
WS-I BP1.0 provides a few guidance here. WSDL2.0 part 1 draft follows similar principle. Put it simple, use wsdl:import to import WSDL files and use xs:import to import xml schemas.
wsdl:import elements are defined as direct children of wsdl:definition, when appear in a wsdl, they MUST precede all other elements from the WSDL namespace exceptwsdl:documentation. wsdl:import can only be used to import other wsdl files. The wsdl:import must have a non-empty location attribute, but the location should only be used as a hint and processors are free to use other means to locate the imported wsdl file. The imported wsdl can be either in the same or different namespace as the importing wsdl file. however, namespace coersion is disallowed. In other words, the targetNamespace attribute on the wsdl:definitions element of a description that is being imported MUST have same the value as the namespace attribute on the wsdl:import element in the importing DESCRIPTION.
xs:import can only be used inside xsd:schema elements under wsdl:types, and its use should follow the XML schmema spec (). When its namespace attribute is specified, it can only be used to import schemas in a different namespaces as the targetnamespace of the enclosing xs:schema element. If its namespace attribute is absent, then the import allows unqualified reference to components with no target namespace.
xs:include should be used to assemble a schema for a single target namespace from multiple schema definition documents.ie. when the imported schema has a same namespace as the enclosing xs:schema element, or has no targetNamespace at all. In the later case, the d schema is converted to the ing schema's targetNamespace.
BP also requires that all xsd:schema elements contained in a wsdl:types element of a DESCRIPTION MUST have a targetNamespace attribute with a valid and non-null value, UNLESS the xsd:schema element has xsd:import and/or xsd:annotation as its only child element(s). It's also worth noting that the target namespace for WSDL definitions and the target namespace for its enclosed MAY be the same, since the names defined by schemas and the names assigned to WSDL definitions are in separate symbol spaces.
Below is an example of a wsdl definition that illustrate the correct use of wsdl:import and xs:import
<definitions name="myWSDL1" targetNamespace="http://example.com/definitions" xmlns:def1= "http://example.com/definitions/base" xmlns:dat1= "http://example.com/schemas" xmlns:dat2= "http://example.com/schemas/import" xmlns="http://schemas.xmlsoap.org/wsdl/"> <import namespace="http://example.com/definitions/base" location="http://example.com/stockquote/stockquote.wsdl"/> <types> <schema targetNamespace="http://example.com/schemas" xmlns="http://www.w3.org/2001/XMLSchema"> <import namespace="http://example.com/stockquote/schemas/import" schemaLocation="http://example.com/stockquote/schemas/myxsd1.xsd" /> <include schemaLocation="http://example.com/stockquote/schemas/myxsd2.xsd" /> ... </schema> </types> ... </definitions>
Visbility of imported components and QName References
According to XML Schema, the visibility of imported component is horizontal which means QName reference works only for components in either the target namespace (maybe via xs:include), or directly in an imported namespace (one marked explicitly with an xsd:import element). QName references to namespaces represented only by nested imports are not allowed.
BP applies the same rules to WSDL 1.1 which is unclear as to which schema target namespaces are suitable for QName references from a WSDL element: A DESCRIPTION MUST NOT use QName references to WSDL components in namespaces that have been neither imported, nor defined in the referring WSDL document. A QName reference to a Schema component in a DESCRIPTION MUST use the namespace defined in the targetNamespace attribute on the xsd:schema element, or to a namespace defined in the namespace attribute on an xsd:import element within the xsd:schema element. QName references to namespaces that are only defined through a nested import are not allowed.
How it works when a wsdl imports another wsdl which has imported schemas?
Say the following wsdl definition tries to import the wsdl named "myWSDL1" as defined in the above example, the schema components are not automatically made available to the importing WSDL.
According to the visibility rules as stated in the above section, only wsdl components in the namespace of http://example. com/definitions are made available to myWSDL2 via Qname reference. If myWSDL2 also needs to references schema components in namespace http://example.com/schemas/import. then it has to import it expicitly.
<definitions name="myWSDL2" targetNamespace="http://example.com/definitions2" xmlns:def= "http://example.com/definitions" xmlns:dat= "http://example.com/schemas/import" xmlns="http://schemas.xmlsoap.org/wsdl/"> <import namespace="http://example.com/definitions" location="http://example.com/stockquote/stockquote2.wsdl"/> <types> <schema xmlns="http://www.w3.org/2001/XMLSchema"> <import namespace="http://example.com/schemas/import" schemaLocation="http://example.com/stockquote/schemas/myxsd1.xsd" /> ... </schema> </types> ... </definitions>
How it works when a wsdl imports another wsdl which has embeded schemas?
The embedded schemas are NOT visible to the importing WSDL. So if you see a schema maybe reused by different WSDLs, you are encouraged to define that schema in its own file and import it to the WSDLs.
How it works when one embedded schema imports another embeded schema within a WSDL?
BP doesn't provide clarification on this situation, but we can borrow the guidance from WSDL2.0 which states that "Inside an embedded XML schema, the xs:import and xs:include element information items MAY be used to refer to other XML schemas embedded in the same WSDL description, provided that an appropriate value is specified for their schemaLocation attribute information items. The semantics of such element information items are governed solely by the XML Schema specification ". In this case, it's considered as a best practice to omit the schemaLocation attribute of xs:import and xs:include.
The following is a valid WSDL example:
<definitions name="myWSDL3" targetNamespace="http://example.com/definitions3" xmlns="http://schemas.xmlsoap.org/wsdl/"> <types> <schema targetNamespace="http://example.com/schemas/ns1" xmlns="http://www.w3.org/2001/XMLSchema"> ... </schema> <schema targetNamespace="http://example.com/schemas/ns2" xmlns="http://www.w3.org/2001/XMLSchema"> <import namespace="http://example.com/schemas/ns1" /> .... </schema> </types> ... </definitions> http://www.ws-i.org/Profiles/BasicProfile-1.0-2004-04-16.html http://www.w3.org/TR/wsdl20/ http://www.w3.org/TR/xmlschema-1/
Kevin Liu is an architect of XML Web Services technologies at SAP Labs California. He helps driving the adoption of web services technologies in SAP's strategic products, as well as represents SAP in various standard bodies.
This weblog originally appeared in the SAP Developer Network. To view original weblog click here. The SAP Developer Network is the central hub for the SAP technology community and is SAP's new collaborative community portal for developers, administrators and consultants. Registration to the SDN community at http://sdn.sap.com is free.
This was first published in June 2004