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.
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
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.
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.
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.
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: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.
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:langattribute 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.
- Participate in the discussion forum.
- Explore the benefits of XML namespaces and how to use them with W3C standard XML formats and tools in David Marston's first article, "Plan to use XML namespaces, Part 1."
- For another look at the subject, read Uche Ogbuji's article "Use XML namespaces with care" (developerWorks, April 2004).
- Discover what XML 1.1 and Namespaces 1.1 are about, what changes they bring, and how they affect other specs and users in "XML 1.1 and Namespaces 1.1 revealed" by Arnaud Le Hors (developerWorks, May 2004).
- The Namespaces in XML 1.0 Recommendation from the W3C sets the standard.
- The XML Schema Recommendation of the W3C has three parts: Primer, Structures, and Datatypes.
- The W3C is developing Architectural Principles about identifiers.
- XInclude is on its way to becoming a W3C recommendation.
- The XML Information Set Recommendation of the W3C is an abstract design that identifies the significance of the parts of an XML tree structure.
- "Real-world XML Schema" offers naming ideas (developerWorks, January 2002).
- Part 6 of Christina Lau's "XML and WebSphere Studio Application Developer" series provides coaching on the use of namespaces in schemas.
- Find out more about MathML, a W3C vocabulary, and Directory Services Markup Language (DSML), which comes from an OASIS Technical Committee.
- See the latest "XPointer xmlns() Scheme" draft for a slightly different way to declare namespaces.
- URI Generic Syntax, RFC 2396, gives plenty of detail on URIs.
- Find more XML resources on the developerWorks
XML technology zone.
- Get Rational Application Developer for WebSphere Software, an easy-to-use, integrated development environment for building, testing, and deploying J2EE applications, including generating XML documents from DTDs and schemas.
- Find out how you can become an IBM Certified Developer in XML and related technologies.
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.