Item 21. Rely on Namespace URIs, Not Prefixes

Namespaces use URIs to distinguish elements and attributes. The prefix is syntax sugar, nothing moreit's the URI that counts, not the prefix. All code you write should depend on the URI, not the prefix. For example, suppose you're writing a Java program that uses the DOM API to search for XLink elements. The following code fragment is correct because it relies on the URI and the local name .

 public boolean isSimpleLink(Element candidate) {   if (candidate.hasAttributeNS("http://www.w3.org/1999/xlink",       "type"); {     return true;   }   return false; } 

However, the following code is incorrect because it assumes the prefix is xlink and does not consider the URI.

 public boolean isSimpleLink(Element candidate) {   if (candidate.hasAttribute("xlink:type"); {     return true;   }   return false; } 

Sometimes the prefix will be xlink . Sometimes it won't be. For instance, the shorter xl prefix is also often used in practice.

Namespace comparison can be a little tricky. For instance, consider the following namespace URIs:

  • http://www.w3.org/1999/02/22-rdf-syntax-ns#

  • http://WWW.W3.ORG/1999/02/22-rdf-syntax-ns#

  • http://www.w3.org/1999/02/22-rdf-syntax-ns%23

  • http://www.w3.org/1999/02/22%2Drdf%2Dsyntax%2Dns#

  • http://www.w3.org/1999/02/22%2drdf%2dsyntax%2dns#

Are they the same or different? If some are different, which ones? The namespaces specification is not clear, which is a very good reason for choosing namespace URIs such that these issues do not arise. That being said, the most common approach, and probably the most interoperable, is to simply compare all namespace URIs character by character, in a case-sensitive fashion, without resolving hexadecimal escape sequences such as %2D.

Some applications have certain common prefixes, and it's kind to use them when authoring. For example, XSL Formatting Objects documents almost always use the prefix fo . Using the customary prefixes helps people recognize particular applications. This is also helpful in documentation such as this book or W3C specifications since it avoids having to place a namespace declaration on every small code fragment. For example, the XLink specification states, "Most code examples in this specification do not show an XLink namespace declaration. The xlink prefix is used throughout to stand for the declaration of the XLink namespace on elements in whose scope the so- marked attribute appears (on the same element that bears the attribute or on some ancestor element), whether or not an XLink namespace declaration is present in the example." [1] However, this is only a documentation convention. In code it's always the URI that's normative, not the prefix.

[1] W3C XML Linking Working Group . "XML Linking Language (XLink) Version 1.0." 2001. Accessed online in June 2003 at http://www.w3.org/TR/xlink/

Table 21-1 lists a few of the common prefixes. However, as this table also shows, several XML applications have more than one customary prefix. Thus you can't rely on the prefix as the final identifier.

It's even possible for a customary prefix to be mapped to a noncustomary URI. For instance, the document on the next page uses the default namespace for the XSLT elements and xsl for the XSL-FO elements in the result tree.

Table 21-1. Customary Prefixes

Application

Namespace

Prefixes

SVG

http://www.w3.org/2000/svg

default, svg

XSLT

http://www.w3.org/1999/Transform

xsl

XSL-FO

http://www.w3.org/1999/Format

fo

XHTML

http://www.w3.org/1999/xhtml

default, html , xhtml

XInclude

http://www.w3.org/2001/XInclude

xi , xinclude

XLink

http://www.w3.org/1999/xlink

xlink , xl

W3C XML Schema Language schema documents

http://www.w3.org/2001/XMLSchema

default, xsd , xs

W3C XML Schema Language instance documents

http://www.w3.org/2001/XMLSchema-instance

xsi

RDF

http://www.w3.org/1999/02/22-rdf-syntax-ns#

default, rdf

 <?xml version="1.0"?> <stylesheet version="1.0"   xmlns="http://www.w3.org/1999/XSL/Transform"   xmlns:fo="http://www.w3.org/1999/XSL/Format">   <template match="/">     <xsl:root>       <xsl:layout-master-set>         <xsl:simple-page-master master-name="basic"            page-width="8.5in"  page-height="11in"            margin-top="1in"    margin-bottom="1in"            margin-left="1in"   margin-right="1in">           <xsl:region-before extent="3.0in"/>           <xsl:region-body margin-top="1.0in"                            margin-bottom="1.0in"/>           <xsl:region-after extent="1.0in"/>         </xsl:simple-page-master>       </xsl:layout-master-set>       <xsl:page-sequence master-reference="A4"         initial-page-number="1" language="en" country="us">         <xsl:flow flow-name="xsl-region-body">           <apply-templates select="//section"/>         </xsl:flow>       </xsl:page-sequence>     </xsl:root>   </template>   <template match="section">     <xsl:block><value-of select="title"/></xsl:block>   </template> </stylesheet> 

This is perverse and confusing, and I certainly recommend you don't do this. It can only confuse anyone who's reading the stylesheet. However, it is completely legal, and properly written software should have no trouble comprehending it.

In a few cases, especially involving XSLT, it may be necessary to use nonstandard prefixes to avoid conflicts. For example, XHTML customarily uses the default namespace. However, XPath can't match element names in the default namespace, so when writing templates that apply to XHTML elements, it's necessary to assign them a prefix. The following template changes XHTML paragraphs into XSL-FO blocks.

 <?xml version="1.0"?> <stylesheet version="1.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   xmlns:html="http://www.w3.org/1999/xhtml"   xmlns:fo="http://www.w3.org/1999/XSL/Format">   <xsl:template match="html:p">     <fo:block><xsl:value-of select="."/></fo:block>   </xsl:template> </xsl:stylesheet> 

Another weird case occurs when you're using XSLT to generate XSLT. In this situation you need to distinguish between the XSLT instructions and the XSLT literal result elements. Changing the prefix is not enough. You also need to change the URI. This requires using the xsl: namespace-alias element to assign a temporary URI for the output elements and let the processor fix up the namespace when it generates the final document. However, this is an extremely unusual thing to do. Most of the time, a little adjustment of the prefixes is all that's required.

The fundamental principle of namespaces is this: The URI matters. The prefix doesn't. Always write code that keys off of the URI, not the prefix. Namespace prefixes are just syntax sugar intended to make XML documents easier to type and read. They do not in any way change the information content of a document.



Effective XML. 50 Specific Ways to Improve Your XML
Effective XML: 50 Specific Ways to Improve Your XML
ISBN: 0321150406
EAN: 2147483647
Year: 2002
Pages: 144

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