A Word About Namespaces
You can get a long way with XML without any knowledge of namespaces,
but you won't get far with XSL! For a start, an XSL processor uses namespaces
to indicate which elements to process itself and which to put directly into the
result tree. Let's start with a quick review of namespaces in general, and then
look at the three main uses of namespaces in XSL.
Because we can define our own element and attribute names in
XML, there is always the chance that we will want to use the same name with
different meanings in a document. If I am processing XML that is describing
metalworking, I might want to create an element in my output called <template>.
As we have seen, XSLT has an element with the same name, so I might try
something like this:
<template match="pattern">
<template><value-of select="."/></template>
</template>
The purpose of XML namespaces is to make our element names
unique. In this case, it would disambiguate my two <template>
elements, so that the XSL processor knows that it must process the first, but
that the second should be copied directly to the output tree.
XML namespaces use a Uniform Resource Identifier
(URI) to
ensure uniqueness of names.
Why a URI? Simply that a key aspect of a URI is that it is unique. When we use
the URI such as http://www.wrox.com /namespaces, a registration authority allocates the domain name
wrox.com to Wrox Press and to nobody else. It is then up to
Wrox to ensure that any URIs within this domain are unique.
So we can make our template elements unique by associating them with a
namespace. One way to do this is with a namespace prefix, and that
is what we have been doing with the XSLT namespace in our examples so far. We
have associated the prefix xsl
with the URI http://www.w3.org/1999/XSL/Transform using the reserved xmlns attribute within our stylesheet element:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
Since the stylesheet
element itself is part of
the XSLT namespace, this also uses the prefix. As you can see, the prefix is
separated from the element name by a colon.
In the terminology of the W3C recommendation (http://www.w3.org/TR/REC-xml-names),
xsl:stylesheet
is a qualified
name (or QName), xsl
is a prefix
and stylesheet
is a local
part.
So we could modify our stylesheet to look like this:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="pattern">
<template><value-of
select="."/></template>
</xsl:template>
</xsl:stylesheet>
Now the XSL processor knows to process the elements starting
xsl:
and to place other elements directly into the result tree.
Let's also declare a namespace for our <pattern>
and <template>
elements:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wrox="http://www.wrox.com/namespaces">
<xsl:template match="wrox:pattern">
<wrox:template><value-of
select="."/></wrox:template>
</xsl:template>
</xsl:stylesheet>
Now that we have done this, we can make either of these
namespaces the default namespace for the document by removing the colon and
prefix in the namespace declaration and the prefix and colon in element and
attribute names that use that namespace. Note that we can do this with either
namespace, so the following two documents are equivalent.
Here is the document with the Wrox namespace as default:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.wrox.com/namespaces">
<xsl:template match="pattern">
<template><value-of select="."/></template>
</xsl:template>
</xsl:stylesheet>
This is the document with the XSLT namespace as default:
<stylesheet
version="1.0"
xmlns="http://www.w3.org/1999/XSL/Transform"
xmlns:wrox="http://www.wrox.com/namespaces">
<template match="wrox:pattern">
<wrox:template><value-of
select="."/></wrox:template>
</template>
</stylesheet>
In the example above, we have used namespaces for three
distinct purposes, although we used the Wrox namespace for two of these:
q
to indicate which elements were part of the XSLT
namespace and so should be processed by the XSL processor
q
to match elements, such as the <pattern>
element, in the source tree only if they belong to a certain namespace
q
to ensure that
elements in the result tree, such as <template>, belong to the namespace we want
Let's just look a little more at matching
namespace-qualified nodes in the source tree. Take the case where we have
a stylesheet that is operating on an XML Schema document. We might have a line
in our stylesheet such as:
<xsl:apply-templates
select="xsd:complexType"/>
If we have not specified the namespace we are using for the xsd
prefix in our stylesheet, our XSLT processor will match on the complete name xsd:complexType
(since the colon is a valid part of an XML element name). If we then have
another schema using xs as a qualifier rather than xsd,
or using the XML Schema namespace as the default, we will no longer get matches
in our stylesheet. This is unlikely to be what we want. By specifying the XML
Schema namespace in our stylesheet, we can be certain that we will match XML
Schema elements whatever prefix they are using, or even if they have no prefix
because they belong in the default namespace of our source document.
In general in this book, we will use the xsl
prefix for XSLT elements and suitable qualifiers for other namespaces.