XML Namespaces

There's considerable freedom in XML because you can define your own tags. However, as more XML applications came to be developed, a problem arose that was unforeseen by the creators of the original XML specification: tag name conflicts.

As we saw in the previous chapter, two popular XML applications are XHTML (that is, HTML 4 as written in XML) and MathML, which lets you display equations. XHTML is useful because it lets you handle all the standard HTML 4 tags. If you need to display equations, MathML can be essential. So what if you want to use MathML inside an XHTML Web page? That's a problem because the tags defined in XHTML and MathML overlap ( specifically , both applications define <var> and <select> elements).

The solution is to use namespaces. Namespaces allow you to make sure that one set of tags cannot conflict with another. Namespaces work by letting you prepend a name followed by a colon to tag and attribute names, changing those names so they don't conflict.

XML namespaces are one of those XML companion recommendations that keep being added to the XML specification; you can find the specification for namespaces at www.w3.org/TR/REC-xml-names/. There's still a lot of debate about this one (largely because namespaces can make writing DTDs difficult), but it's now an official W3C recommendation.

Creating a Namespace

Here's an example. In this case, I'll use a fictitious XML application designed for cataloging books whose root element is <library> , and I'll add my own reviews to each book. I start off with a book as specified with the fictitious XML application:

 <library>     <book>         <title>             Earthquakes for Lunch.         </title>    </book> </library> 

Now I want to add my own comments to this <book> item. To do that, I will start by confining the book XML application to its own namespace, for which I'll use the prefix book: . To define a new namespace, you use the xmlns: prefix attribute, where prefix is the prefix you want to use for the namespace, like this:

 <library  xmlns:book="http://www.amazingterrificbooks.com/spec">  <book>         <title>             Earthquakes for Lunch.         </title>    </book> </library> 

To define a namespace, you assign the xmlns: prefix attribute to a unique identifier, which in XML is usually a URI (read URL, in this case) that may direct the XML processor to a DTD for the namespace (but that doesn't have to). After defining the book namespace, you can preface every tag and attribute name in this namespace with book: , like this:

 <book:library     xmlns:book="http://www.amazingterrificbooks.com/spec">    <book:book>         <book:title>             Earthquakes for Lunch.         </book:title>    </book:book> </book:library> 

Now the tag and attribute names have actually been changed; for example, <library> is now <book:library> , as far as the XML processor is concerned . (If you've defined tag and attribute names in a document's DTD, this means that you have to redefine the tags and attributes there as well to make the new names legal.)

Because all tag and attribute names from the book namespace are now in their own namespace, I'm free to add my own namespace to the document to allow me to add my own comments to each book entry. I start by defining a new namespace named steve :

  <book:library   xmlns:book="http://www.amazingterrificbooks.com/spec"   xmlns:steve="http://www.starpowder.com/steve">  <book:book>         <book:title>             Earthquakes for Lunch.         </book:title>    </book:book> </book:library> 

Now I can use the new steve namespace to add markup to the document like this, keeping it separate from the other markup:

 <book:library     xmlns:book="http://www.amazingterrificbooks.com/spec"    xmlns:steve="http://www.starpowder.com/steve">    <book:book>         <book:title>             Earthquakes for Lunch.         </book:title>  <steve:review>   This book was OK, no great shakes.   </steve:review>  </book:book> </book:library> 

I can also use attributes in the steve namespace as long as I prefix them with steve: , like this:

 <book:library     xmlns:book="http://www.amazingterrificbooks.com/spec"    xmlns:steve="http://www.starpowder.com/steve">    <book:book>         <book:title>             Earthquakes for Lunch.         </book:title>  <steve:review steve:ID="1000034">   This book was OK, no great shakes.   </steve:review>  </book:book> </book:library> 

And that's how namespaces workyou can use them to separate tags, even tags with the same name, from each other. As you can see, using multiple namespaces in the same document is no problem at all. Just use the xmlns attribute in the enclosing element to define the appropriate namespaces.

xmlns in Child Elements

In fact, you can use the xmlns attribute in child elements to redefine an enclosing namespace if you want to.

Creating Local Namespaces

You don't need to use the xmlns attribute in the root element. You can use this attribute in any element as in this case, where I've moved the steve namespace definition to the element in which it's used:

 <book:library     xmlns:book="http://www.amazingterrificbooks.com/spec">    <book:book>         <book:title>             Earthquakes for Lunch.         </book:title>  <steve:review   xmlns:steve="http://www.starpowder.com/steve"   steve:ID="1000034">   This book was OK, no great shakes.   </steve:review>  </book:book> </book:library> 

Because namespace prefixes are really just text prepended to tag and attribute names, they follow the same rules for naming tags and attributesthat is, a namespace can start with a letter or an underscore . The following characters can include underscores, letters , digits, hyphens, and periods. Although colons are legal in tag names, you can't use a colon in a namespace name, for obvious reasons. In addition, two namespace names are reserved: xml and xmlns . Note that because namespace prefixes are merely text prepended to tag and attribute names, followed by a colon (which is legal in names), XML processors that have never heard of namespaces can use them without problem.

Names of Attributes in Namespaces

You can use two names to refer to the same namespace. Note, however, that because you must use attributes with unique names, you cannot use attributes with two namespaces that share the same name in the same element.

Default Namespaces

Now I'll return to the example that introduced this topic: the idea of using MathML in an XHTML document. In this case, I'll assume that I want to display an equation in an XHTML document. I start off with an XHTML document that looks like this:

 <?xml version="1.0"?>  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/tr/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">     <head>         <title>             Embedding MathML In XHTML         </title>     </head>     <body>         <center>             <h1>                 Embedding MathML In XHTML             </h1>         </center>         Here's the MathML:     </body> </html> 

This document has a <!DOCTYPE> element that you use to connect a DTD to a document, and the <html> element defines a namespace with the xmlns attribute. Note in particular that, this time, the xmlns attribute is used by itself, without defining any prefix to specify a namespace ( xmlns="http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml" ). When you use the xmlns attribute alone without specifying any prefix, you are defining a default namespace. All the enclosed elements are assumed to belong to that namespace.

In XHTML documents, it's customary to make the W3C XHTML namespace, http://www.w3.org/1999/xhtml , into the default namespace for the document. When you do, you can then use the standard HTML tag names without any prefixes, as you see in this example.

However, I want to use MathML markup in this document. To do so, I add a new namespace, which I'll call m , to this document using the namespace that the W3C has specified for MathML, http://www.w3.org/1998/Math/MathML/ :

 <?xml version="1.0"?>  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/tr/xhtml1/DTD/xhtml1-transitional.dtd">  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"   xmlns:m="http://www.w3.org/1998/Math/MathML/">  <head>         <title>             Embedding MathML In XHTML         </title>     </head>     <body>         <center>             <h1>                 Embedding MathML In XHTML             </h1>         </center>         Here's the MathML:     </body> </html> 

Now I can add MathML as I like, as long as I restrict that markup to the m namespace like this:

 <?xml version="1.0"?>  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/tr/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"     xmlns:m="http://www.w3.org/1998/Math/MathML/">     <head>         <title>             Embedding MathML In XHTML         </title>     </head>     <body>         <center>             <h1>                 Embedding MathML In XHTML             </h1>         </center>         Here's the MathML:  <m:math>   <m:mrow>   <m:mrow>   <m:mn>3</m:mn>   <m:mo>&InvisibleTimes;</m:mo>   <m:msup>   <m:mi>Z</m:mi>   <m:mn>2</m:mn>   </m:msup>   <m:mo>-</m:mo>   <m:mrow>   <m:mn>6</m:mn>   <m:mo>&InvisibleTimes;</m:mo>   <m:mi>Z</m:mi>   </m:mrow>   <m:mo>+</m:mo>   <m:mn>12</m:mn>   </m:mrow>   <m:mo>=</m:mo>   <m:mn>0</m:mn>   </m:mrow>   </m:math>  </body> </html> 

This document works fine, and you can see the result in the W3C Amaya browser in Figure 2-3.

Figure 2-3. The MathML markup in the Amaya browser.

graphics/02fig03.gif

We'll have occasion to use namespaces throughout this book, as when we work with the XSL transformation language.



Real World XML
Real World XML (2nd Edition)
ISBN: 0735712867
EAN: 2147483647
Year: 2005
Pages: 440
Authors: Steve Holzner

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net