Skip to main content

If you don't have an IBM ID and password, register here.

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

The first time you sign into developerWorks, a profile is created for you. This profile includes the first name, last name, and display name you identified when you registered with developerWorks. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

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.

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

All information submitted is secure.

Web services Programming Tips and Tricks: WSDL file imports

Russell Butek (butek@us.ibm.com), Software Engineer, EMC
Russell Butek is an IBM Web services consultant. He has been one of the developers of the IBM WebSphere Web services engine. He is also a member the JAX-RPC Java Specification Request (JSR) expert group. He was involved in the implementation of Apache's AXIS SOAP engine, driving AXIS 1.0 to comply with JAX-RPC 1.0. Previously, he was a developer of the IBM CORBA ORB and an IBM representative on a number of OMG task forces, including chairing the portable interceptor task force. Contact Russell at butek@us.ibm.com.
(An IBM developerWorks Contributing Author)

Summary:  This tip explains the nuances of the two types of import statements found in a Web Services Description Language (WSDL) file.

Date:  09 Jul 2004
Level:  Intermediate

Comments:  

Import statements are easy, right? Just about every programming or interface language has them; and if you're reading this tip, you probably know everything there is to know about imports. So, why should you read a tip about Web Services Description Language (WSDL) file imports? For one thing, two types of import statements exist: XSD imports and WDSL imports. For another, their respective behaviors are not quite identical. Lastly, it's a good idea to know the relationship between the two.

Import vs. include

Before I dive into describing the import statements, let me make the distinction between an import and an include. An import statement brings in other namespaces. An include statement brings other declarations into the current namespace.


XSD import

Let's look at a basic XSD import, such as the one highlighted in red in Listing 1. All that this statement does is import a namespace from one schema to another. The schema, which defines the namespace of urn:listing2, is importing the schema of urn:listing3. That's it. No file is being imported. Both schemas are in this same file in Listing 1.


Listing 1. Address book WSDL using two namespaces
<?xml version="1.0" ?>
<wsdl:definitions targetNamespace="urn:listing2"
                  xmlns:tns="urn:listing2"
                  xmlns:listing3="urn:listing3"
                  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <wsdl:types>
    <xsd:schema targetNamespace="urn:listing3"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <xsd:import namespace="http://www.w3.org/2001/XMLSchema"/>
      <xsd:complexType name="Phone">
        <xsd:sequence>
          <xsd:element name="areaCode" type="xsd:int"/>
          <xsd:element name="exchange" type="xsd:int"/>
          <xsd:element name="number" type="xsd:int"/>
        </xsd:sequence>
      </xsd:complexType>
    </xsd:schema>
    <xsd:schema targetNamespace="urn:listing2"
                xmlns:listing3="urn:listing3"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <xsd:import namespace="urn:listing3"/>
      <xsd:import namespace="http://www.w3.org/2001/XMLSchema"/> <xsd:complexType name="Address"> <xsd:sequence> <xsd:element name="streetNum" type="xsd:int"/> <xsd:element name="streetName" type="xsd:string"/> <xsd:element name="city" type="xsd:string"/> <xsd:element name="state" type="xsd:string"/> <xsd:element name="phone" type="listing3:Phone"/> </xsd:sequence> </xsd:complexType> </xsd:schema> </wsdl:types> <wsdl:message name="GetAddressRequest"> <wsdl:part name="name" type="xsd:string"/> </wsdl:message> <wsdl:message name="GetAddressResponse"> <wsdl:part name="address" type="tns:Address"/> </wsdl:message> <wsdl:message name="GetPhoneRequest"> <wsdl:part name="name" type="xsd:string"/> </wsdl:message> <wsdl:message name="GetPhoneResponse"> <wsdl:part name="phone" type="listing3:Phone"/> </wsdl:message> <wsdl:portType name="AddressBook"> <wsdl:operation name="getAddress"> <wsdl:input message="tns:GetAddressRequest"/> <wsdl:output message="tns:GetAddressResponse"/> </wsdl:operation> <wsdl:operation name="getPhone"> <wsdl:input message="tns:GetPhoneRequest"/> <wsdl:output message="tns:GetPhoneResponse"/> </wsdl:operation> </wsdl:portType> </wsdl:definitions>

Hopefully, it's clear from the example in Listing 1 that the primary purpose of an import is to import a namespace. A more common use of the XSD import statement is to import a namespace which appears in another file. You might be gathering the namespace information from the file, but don't forget that it's the namespace that you're importing, not the file (don't confuse an import statement with an include statement).

When you're importing a namespace from a file, you will see a schemaLocation attribute on the XSD import statement, but it is an optional attribute. As you can see in Listing 1, schemaLocation is not necessary because the namespace of the import statement is at the same location (in the same file) as the import statement itself. In fact, even if you had provided a file location (as Listing 2 does), an XML parser is free to ignore the location if it wishes. The schemaLocation attribute is merely a hint. If the parser already knows about the schema types in that namespace, or has some other means of finding them, it does not have to go to the location you gave it. This behavior should be another hint to you that the primary purpose of the XSD import statement is to import the namespace, not tell you where you can find the declarations in that namespace. Of course, most of the time you will be importing namespaces that the XML parser knows nothing about, so the schemaLocation attribute becomes necessary, and it's easy to forget that it's only a hint.

Now, take a look at the import statements I highlighted in blue in Listing 1. Since I use the XSD namespace, I should really import it. But this is a very common namespace. Virtually every XML parser inherently knows about it. Most parsers are rather forgiving about including the import statement for it. In fact, many tools even forgive you if you neglect to include the red import statement -- the imported namespace is in the same file, after all -- but you should really make a habit of importing all namespaces that you use. You never know when you, or someone who uses your WSDL file, might use a stricter tool.

Be very sure that the namespace you use in the import statement is the same as the targetNamespace of the schema you are importing. In the example in Listing 1, it's fairly obvious that you have to do this. But if you move the urn:listing3 schema into a file called listing3.xml, and import that file (as Listing 2 does), then it might not be so obvious. In fact, it might look like you can change the namespace of the schema in the file by using a different namespace attribute on the import statement than in the targetNamespace. This is a mistake. You cannot change namespaces. The namespace attribute of the import statement must match the targetNamespace of the schema.

Listings 2 and 3 are derived from Listing 1. Listing 2 is Listing 1 with the Phone schema removed to a different file -- the file in Listing 3. The import statement in Listing 2 now includes the schemaLocation attribute (highlighted in blue). This is the recommended way to import schema from a file.


Listing 2. Address Book WSDL importing XSD file for Phone schema
<?xml version="1.0" ?>
<wsdl:definitions targetNamespace="urn:listing2"
                  xmlns:tns="urn:listing2"
                  xmlns:listing3="urn:listing3"
                  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
  <wsdl:types>
    <xsd:schema targetNamespace="urn:listing2"
                xmlns:listing3="urn:listing3"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <xsd:import namespace="urn:listing3" schemaLocation="listing3.xsd"/>
      <xsd:import namespace="http://www.w3.org/2001/XMLSchema"/>
      <xsd:complexType name="Address">
        <xsd:sequence>
          <xsd:element name="streetNum" type="xsd:int"/>
          <xsd:element name="streetName" type="xsd:string"/>
          <xsd:element name="city" type="xsd:string"/>
          <xsd:element name="state" type="xsd:string"/>
          <xsd:element name="phone" type="listing3:Phone"/>
        </xsd:sequence>
      </xsd:complexType>
    </xsd:schema>
  </wsdl:types>

  <wsdl:message name="GetAddressRequest">
    <wsdl:part name="name" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="GetAddressResponse">
    <wsdl:part name="address" type="tns:Address"/>
  </wsdl:message>
  <wsdl:message name="GetPhoneRequest">
    <wsdl:part name="name" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="GetPhoneResponse">
    <wsdl:part name="phone" type="listing3:Phone"/>
  </wsdl:message>

  <wsdl:portType name="AddressBook">
    <wsdl:operation name="getAddress">
      <wsdl:input message="tns:GetAddressRequest"/>
      <wsdl:output message="tns:GetAddressResponse"/>
    </wsdl:operation>
    <wsdl:operation name="getPhone">
      <wsdl:input message="tns:GetPhoneRequest"/>
      <wsdl:output message="tns:GetPhoneResponse"/>
    </wsdl:operation>
  </wsdl:portType>
</wsdl:definitions>


Listing 3. XSD file for Phone schema
<?xml version="1.0" ?>
<xsd:schema targetNamespace="urn:listing3"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:import namespace="http://www.w3.org/2001/XMLSchema"/>
  <xsd:complexType name="Phone">
    <xsd:sequence>
      <xsd:element name="areaCode" type="xsd:int"/>
      <xsd:element name="exchange" type="xsd:int"/>
      <xsd:element name="number" type="xsd:int"/>
    </xsd:sequence>
  </xsd:complexType>
</xsd:schema>


WSDL import

Take a look at Listings 4 and 5. They are essentially the same as Listings 2 and 3. Listing 4 imports Listing 5 as Listing 2 imports Listing 3. But this time, I used a WSDL import rather than an XSD import. The differences between Listing 2 and Listing 4 are highlighted in blue in Listing 4. Likewise, the differences between Listing 3 and Listing 5 are highlighted in blue in Listing 5.


Listing 4. Address Book WSDL importing WSDL file for Phone schema
<?xml version="1.0" ?>
<wsdl:definitions targetNamespace="urn:listing4"
                  xmlns:tns="urn:listing4"
                  xmlns:listing5="urn:listing5"
                  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
  <wsdl:import namespace="urn:listing5" location="listing5.wsdl"/>
  <wsdl:types>
    <xsd:schema targetNamespace="urn:listing4"
                xmlns:listing5="urn:listing5"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <xsd:import namespace="http://www.w3.org/2001/XMLSchema"/>
      <xsd:complexType name="Address">
        <xsd:sequence>
          <xsd:element name="streetNum" type="xsd:int"/>
          <xsd:element name="streetName" type="xsd:string"/>
          <xsd:element name="city" type="xsd:string"/>
          <xsd:element name="state" type="xsd:string"/>
          <xsd:element name="phone" type="listing5:Phone"/>
        </xsd:sequence>
      </xsd:complexType>
    </xsd:schema>
  </wsdl:types>

  <wsdl:message name="GetAddressRequest">
    <wsdl:part name="name" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="GetAddressResponse">
    <wsdl:part name="address" type="tns:Address"/>
  </wsdl:message>
  <wsdl:message name="GetPhoneRequest">
    <wsdl:part name="name" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="GetPhoneResponse">
    <wsdl:part name="phone" type="listing5:Phone"/>
  </wsdl:message>

  <wsdl:portType name="AddressBook">
    <wsdl:operation name="getAddress">
      <wsdl:input message="tns:GetAddressRequest"/>
      <wsdl:output message="tns:GetAddressResponse"/>
    </wsdl:operation>
    <wsdl:operation name="getPhone">
      <wsdl:input message="tns:GetPhoneRequest"/>
      <wsdl:output message="tns:GetPhoneResponse"/>
    </wsdl:operation>
  </wsdl:portType>
</wsdl:definitions>


Listing 5. WSDL file for Phone schema
<?xml version="1.0" ?>
<wsdl:definitions targetNamespace="urn:listing5"
                  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <wsdl:types>
    <xsd:schema targetNamespace="urn:listing5"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <xsd:import namespace="http://www.w3.org/2001/XMLSchema"/>
      <xsd:complexType name="Phone">
        <xsd:sequence>
          <xsd:element name="areaCode" type="xsd:int"/>
          <xsd:element name="exchange" type="xsd:int"/>
          <xsd:element name="number" type="xsd:int"/>
        </xsd:sequence>
      </xsd:complexType>
    </xsd:schema>
  </wsdl:types>
</wsdl:definitions>

Is this a good thing to do? If you run your favorite WSDL-to-Java tool on listing4.wsdl, you should get an error. In Listing 4, I've highlighted two references to the Phone type, one in green and one in red. The green reference is in a WSDL message statement. This statement finds Phone because it is a WSDL statement, and the WSDL file imports Phone via a WSDL import statement. The red reference is in the schema. This reference does not find Phone because it wasn't imported via an XSD import. You cannot step outside of a schema to find other schemas. You must import schemas from inside schemas.

If the Address type did not have a phone element and, therefore, did not reference the urn:listing5 namespace, then this pair, Listings 4 and 5, would be legal. However, it is not a good practice to import schema information with a WSDL import. Listings 2 and 3 are preferred over Listings 4 and 5. Use XSD import to import schema. Use WSDL import to import WSDL.

For an example of proper WSDL imports, you'll notice that Listing 4 doesn't have a binding nor a service statement. Presumably some other file, which contains a binding and a service, will import listing4.wsdl via a WSDL import statement.

A couple of last comments about WSDL imports. Like an XSD import, the namespace attribute of the WSDL import must be the same as the targetNamespace of the imported WSDL. The location attribute of the WSDL import, like the schemaLocation attribute of the XSD import, is just a hint. However, unlike the schemaLocation of the XSD import, the location attribute of the WSDL import is required to be present. (This is not clear in the WSDL 1.1 specification, but the Basic Profile on the WS-I Web site clarifies this. (See Resources.)


Summary

In short, what this tip is trying to say is:

  • It is a good practice to use XSD imports to import schema, and to use WSDL imports to import WSDL.
  • It is a good practice to import all of the namespaces that you use.
  • An attribute value of the import namespace must match the imported targetNamespace value.
  • The primary purpose of an import statement is to import namespaces. The schemaLocation and location attributes, though sometimes necessary, are really only hints.

Resources

About the author

developerWorks Contributing author level

Russell Butek is an IBM Web services consultant. He has been one of the developers of the IBM WebSphere Web services engine. He is also a member the JAX-RPC Java Specification Request (JSR) expert group. He was involved in the implementation of Apache's AXIS SOAP engine, driving AXIS 1.0 to comply with JAX-RPC 1.0. Previously, he was a developer of the IBM CORBA ORB and an IBM representative on a number of OMG task forces, including chairing the portable interceptor task force. Contact Russell at butek@us.ibm.com.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in

If you don't have an IBM ID and password, register here.


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. This profile includes the first name, last name, and display name you identified when you registered with developerWorks. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

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.

(Must be between 3 – 31 characters.)


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

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=SOA and web services
ArticleID=11939
ArticleTitle=Web services Programming Tips and Tricks: WSDL file imports
publish-date=07092004
author1-email=butek@us.ibm.com
author1-email-cc=

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).