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.

Plan to use XML namespaces, Part 2

Combine XML vocabularies and define vocabularies of your own

David Marston, Engineer, IBM Research
David Marston has been working with XML technologies since late 1998. Over his 25+ years in the computing business, he has been involved with all aspects of software development. He is a graduate of Dartmouth College and a member of the ACM. He is on the Next-Generation Web team at IBM Research. You can contact him at David_Marston@us.ibm.com.

Summary:  This two-part article introduces XML namespaces, explores their practical benefits, and shows you how they are used in the standard XML formats and tools defined by the W3C. Here in part 2, David shows you how to intermix XML vocabularies and define vocabularies of your own, with several best practices highlighted. Best practices range from terminology usage up through system-wide design.

Date:  29 Apr 2004 (Published 01 Nov 2002)
Level:  Intermediate

Comments:  

Note: This document mentions changes proposed up through the September 2002 "Last Call Working Draft" of version 1.1 of Namespaces in XML.

In Part 1, you saw how the World Wide Web Consortium (W3C) establishes precedents in its own use of XML namespaces. Part 1 also presented a consistent set of terms for use in discussions on this topic. The most substantial discussions will be about establishing your own XML vocabularies.

Intermixing names in your XML

An element associated with a particular namespace can have child elements and attributes that belong to other namespaces. Here's an example where the data itself employs five namespaces, all with prefixes, declared outside this example element:

<snac:delivery>
  <dc:date>20020717</dc:date>
  <snac:recipient>725577</snac:recipient>
  <upc:upc1>0-30000-06410-8</upc:upc1>
  <snac:size-each>
    <snac:value>3</snac:value>
    <wm:weight>imperial-ounce</wm:weight>
  </snac:size-each>
  <snac:quantity>48</snac:quantity>
  <snac:invoice-price>
    <snac:money-amount>1.54</snac:money-amount>
    <fin:currency>us-dollar</fin:currency>
  </snac:invoice-price>
</snac:delivery>

In this example, the creators of the snac namespace have defined only those elements that are not already established by other consortia. In their design, the delivery element relies upon other namespaces for dates, UPC codes, weights and measures, and names of currencies.

Alternatively, you can apply a namespace to certain attributes, like this:

<snac:size-each value="3" wm:weight="imperial-ounce" />

There is less support built into XML, but you can apply a namespace to a text string, like this:

<snac:size-each value="3" weight="wm:imperial-ounce" />

In this example, the snac:size-each element is defined to have value and weight attributes, with the latter containing a string from an enumerated list of wm strings that are standard names for weights and measures. XML Schema has a QName data type that is a good choice when you want to constrain a string to be a qualified name. (The other XML items that can be named, such as processing-instruction targets and entities, cannot have a name qualified with a namespace. Their names are not allowed to contain colons, although parsers may not enforce that rule.)

It is a best practice to treat namespaces as a way to separate or isolate terms that may otherwise seem similar. Do not use namespaces as mere carriers of bits of information for related elements; use attributes instead.

For example, in one situation a person tried to process all card elements, regardless of whether they were red:card, blue:card, and so forth. (Element names have been changed to protect the guilty.) This is namespace abuse because the different kinds of cards apparently have something in common, whereas prefixes should convey that the different kinds of cards are totally unrelated. The color should have been an attribute.

Creating your own namespaces

You may want to develop one or more XML vocabularies strictly for internal use. If there is going to be just one, you might successfully avoid applying a namespace, but the best practice is to apply namespaces to your own vocabulary, even when there is just one. One good reason to do this is that you may want to introduce new versions in the future. (If there's one thing you can count on in data processing, it's the demand for enhancements!)

Applying a namespace simply means that you pick a URI under a domain name that you control, and define that URI to be the namespace URI for a particular set of XML tags. If you have a systematic way of using the tags, you probably have a design document that explains the rules for each tag; the definition of the applicable namespace URI could be a sentence or two in that design document. If you want to express the design and rules in XML, consider XML schemas.

The best practice in URI management is to coordinate naming under your domain name just as you do for names of machines on your network and your Web URLs. To start, reserve a URL like http://www.example.com/namespace/ or http://namespace.example.com/ as the root of all namespace URIs under your domain name. (Hint: if you have an IS Department that doesn't understand XML, just request a machine named "namespace" as a node on your network, then make the fully-qualified domain name of that machine the root of your namespace URIs.) Once you have a root name established, add on extra fields to specify vocabulary names and version numbers.

Namespaces allow projects to commence while still enabling later modifications and enhancements. Assume that there will be new XML elements and attributes in the future. If you have multiple projects instituting XML that are progressing in parallel and loosely coordinated, give each project a separate namespace. For example, a company that wants to use XML in new Bill Of Materials and Procurement projects might designate http://namespace.example.com/BOM/V1 and http://namespace.example.com/Procurement/V1 as the respective URIs. If the people designing the two vocabularies want to have some elements in common, they can choose one namespace to hold those common items (the best practice), but they are also free to work separately. Furthermore, they may plan on Version 1 ("V1" in the URI) being the vocabulary that uses names from a prior non-XML system, and separately plan "V2" names under a clean slate design.

It is a best practice to change the namespace URI for every substantive change to the vocabulary, including addition of new elements forming a strict superset of the old vocabulary. Under that policy, you can perform schema validation on any version and even retrofit a schema to a version that didn't have one when it was first published.

The Namespaces in XML Recommendation says that the identifier can be a "URI reference" rather than just a URI. The difference is described in part 4 of RFC 2396, but the best practice is to use ordinary URIs.

A URI reference (and an IRI reference, when they begin to appear) can be relative, but relative URIs have been deprecated for namespace use. The W3C appears to be moving toward treating the namespace URI as a string that does not need to be resolved against some frame of reference. A URI reference can have a fragment identifier after the # sign, but the RFC specifically limits fragment usage to retrieval of material. Namespace URIs are not for retrieval, as described in Part 1.

When documenting your own XML vocabularies, you may need to refer to the URIs of customers, suppliers, or other partners with whom you will exchange data. One best practice, defined in RFC 2606, is to use the domain names example.com, example.net, and/or example.org for examples in your documentation.


Transformations can change names

The W3C requires that XSLT transformation processors recognize and work with namespaces. XSLT can be used to take XML of a particular structure (schema) and transform it into XML having the same structure but with some or all names changed. Of course, XSLT can also restructure XML, too. As names are changed, the applicable namespace can be changed, which is useful if you have older XML that needs to be converted to a newer schema whose namespace is different. This can be especially useful when the old XML documents use a default namespace that you want to convert to a prefixed namespace.

XSLT examples

Here are some examples of renaming in XSLT. I start with an example that does not involve namespaces, then expand the baseline example so you can see the difference.

If you want to copy an XML document, but change the names of all elements named name_to_change in the input, the crucial template might look like this:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<!-- Other templates... -->

<xsl:template match="name_to_change">
<new_name>
  <!-- First copy the attributes, then the children. -->
  <xsl:copy-of select="@*"/>
  <xsl:copy-of select="*"/>
</new_name>
</xsl:template>

</xsl:stylesheet>

The above assumes that both the old and new names are unqualified (have no namespace). Other variations are possible.

If you want to copy an XML document, but apply a namespace to all elements named name_to_change in the input, you must declare the namespace in the stylesheet, and associate new_name with it:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ourspace="http://www.example.com/namespace/data1" >

<!-- Other templates... -->

<xsl:template match="name_to_change">
<ourspace:new_name>
  <!-- First copy the attributes, then the children. -->
  <xsl:copy-of select="@*"/>
  <xsl:copy-of select="*"/>
</ourspace:new_name>
</xsl:template>

</xsl:stylesheet>

This time, the old names are unqualified and at least this one element is in the new namespace (ourspace prefix) with a new name (new_name is the local part of the name).

To copy an XML document, but rename an element from one qualified name to another, you need to match namespace URIs between the input document and the stylesheet. In the example below, all elements named zz:name_to_change in the input -- where zz is associated with the URI "http://example.com/namespace/orders" by way of an xmlns declaration within the input document -- will become ourspace:new_name elements in the result. Observe that the stylesheet does not need to know whether zz or some other prefix is used in the input, because it will separately resolve the prefix to a URI in each document (input and stylesheet), and then match the URIs.

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:theirspace="http://example.com/namespace/orders"
xmlns:ourspace="http://www.fictitious.com/namespace/data/V1" 
exclude-result-prefixes="theirspace">

<!-- Other templates... -->

<xsl:template match="theirspace:name_to_change">
<ourspace:new_name>
  <!-- First copy the attributes, then the children. -->
  <xsl:copy-of select="@*"/>
  <xsl:copy-of select="*"/>
</ourspace:new_name>
</xsl:template>

</xsl:stylesheet>

To clean up the result, I designated the namespace from the input on the exclude-result-prefixes list, assuming that all elements (and attributes and keyword strings) in that namespace will be renamed into other namespaces. This means I won't need a declaration for theirspace in the result.

The XSLT Recommendation allows an XSLT processor to use prefixes that it has fabricated even when the stylesheet provides a prefix to be used. I don't know of any XSLT processor that changes prefixes when it doesn't need to, which is good. By giving you the prefix you've asked for, the processor helps you follow these best practices.

As mentioned earlier, XSLT has named objects known only within its stylesheets, as well as the ability to specify the names of elements, attributes, and processing instructions that it creates. Templates can be named, and those names can be qualified to namespaces, but the namespaces of the templates won't affect the input or output XML documents. If the output is XML, you can use exclude-result-prefixes in the stylesheet to suppress creation of a namespace declaration in the output when the namespace was only used within the stylesheets. For example, a stylesheet might have both <xsl:template name="system:max"> and <xsl:element name="fin:currency"> with appropriate content in each. Since xsl:element creates an element in the output, it's necessary to let the XSLT processor create a namespace declaration for the fin namespace, as well. Indeed, exclude-result-prefixes won't suppress the declaration if it's needed. You can use exclude-result-prefixes to suppress the system namespace in the output, if it's used strictly for template names.


Best practice summary

Planning your namespaces

  • Establish logical and consistent prefix names to boost developer productivity.
  • Use prefixes everywhere or at least use them on all items except those that are the real content being delivered to the end user.
  • Apply namespaces to your own vocabulary, even when there is just one.
  • Treat namespaces as a way to separate or isolate terms that may otherwise seem similar.
  • When designing two vocabularies that have some elements in common, choose one namespace (possibly separate from the original two) to hold the common items.
  • Use HTTP URLs for your URIs, without fragment identifiers.
  • Coordinate URI naming under your domain name just as you do for names of machines on your network and your Web URLs.
  • Change the namespace URI for every substantive change to the vocabulary, including the addition of new elements forming a strict superset of the old vocabulary.

Usage inside XML documents

  • If possible, use one prefix for one namespace throughout all XML documents in a system.
  • Declare namespaces explicitly within each document, reducing assumptions and dependencies.
  • Make all namespace declarations up in the start tag of the document element if at all possible.
  • For W3C-defined elements and attributes, use the prefixes that the W3C uses.
  • Use the xml:lang attribute to declare that the content of the element is in a particular natural language.

Documentation and conversational usage

  • Refer to a "namespace declaration" as distinct from an "attribute" when discussing entries in a start tag.
  • Avoid the term "namespace name" or only use it in a context where it's clear what you mean.
  • Use the domain names example.com, example.net, or example.org for examples in your documentation.

Resources

About the author

David Marston has been working with XML technologies since late 1998. Over his 25+ years in the computing business, he has been involved with all aspects of software development. He is a graduate of Dartmouth College and a member of the ACM. He is on the Next-Generation Web team at IBM Research. You can contact him at David_Marston@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=XML
ArticleID=12183
ArticleTitle=Plan to use XML namespaces, Part 2
publish-date=04292004
author1-email=David_Marston@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).