Namespaces and Your Result Document
What if you want your result document to include elements from a specified namespace? Simply declare and use the namespace you need in your stylesheet and the XSLT processor will
- put that namespace declaration in the start-tag of the result document's document element, and
- put the prefix for that namespace in the tags for any result tree elements from that namespace.
For example, to convert the following HTML document to an XLink document, the result needs an XLink namespace declaration and each of the special XLink attributes need a prefix that references that declaration.
<html><body>
<p>The poem's <a href="jmilton.html">author</a> was English.</p>
</body></html>
The stylesheet declares the http://www.w3.org/1999/xlink namespace in the xsl:stylesheet element's start-tag along with the declaration of the http://www.w3.org/ 1999/XSL/Transform namespace.
<xsl:stylesheet xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"
xmlns:xlink= "http://www.w3.org/1999/xlink"
version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:template match="a">
<author xlink:type="simple" xlink:href="{@href}">
<xsl:apply-templates/></author>
</xsl:template>
<xsl:template match="p">
<para><xsl:apply-templates/></para>
</xsl:template>
</xsl:stylesheet>
You'll usually find a namespace declaration in a document element's start-tag, and the XSLT processor passes this declaration along to the start-tag of the result document's document element. It also passes all references to that namespace along to the result tree, making the result document a working XLink document.
<para xmlns:xlink= "http://www.w3.org/1999/xlink">
The poem's <author xlink:type="simple" xlink:href="jmilton.html">
author</author> was English.</para>
In XSLT terms, the XSLT processor has added a namespace node to the result tree. (There are six kinds of nodes that may show up in source and result trees: elements, attributes, text nodes, processing instructions, comments, and namespace nodes.) You can prevent this from happening with the xsl:stylesheet element's exclude-result-prefixes attribute. This attribute's name can be confusing, because the namespace prefixes will still show up in the result tree. It doesn't mean "exclude the prefixes in the result"; it means "exclude the namespaces with these prefixes".
For example, the following stylesheet looks just like the one above with the addition of this attribute to tell the XSLT processor to exclude the namespace node represented by the "xlink" prefix. You can list multiple namespace prefixes as the value of the exclude-result-prefixes attribute, as long as they have spaces between them and they're all declared namespaces.
<xsl:stylesheet xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"
xmlns:xlink= "http://www.w3.org/1999/xlink"
exclude-result-prefixes="xlink"
version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:template match="a">
<author xlink:type="simple" xlink:href="{@href}">
<xsl:apply-templates/></author>
</xsl:template>
<xsl:template match="p">
<para><xsl:apply-templates/></para>
</xsl:template>
</xsl:stylesheet>
Processing the same source document with this stylesheet creates a similar result, except that the document element's start-tag doesn't have the declaration for the XLink namespace:
<para>
The poem's <author xmlns:xlink= "http://www.w3.org/1999/xlink"
xlink:type="simple" xlink:href="jmilton.html">
author</author> was English.</para>
You can also assign result tree elements and attributes to specific namespaces by adding a namespace attribute to the xsl:element instruction or to an xsl:attribute instruction. For example, the second xsl:element instruction in the following template and the two xsl:attribute elements inside of the first xsl:element each include a namespace attribute along with their name attributes. These identify the two namespaces where the element and attribute names belong: the HTML and XLink namespaces.
<xsl:template match="xdata">
<section>
<xsl:element name="author">
<xsl:attribute namespace= "http://www.w3.org/1999/xlink"
name="type" >simple</xsl:attribute>
<xsl:attribute namespace= "http://www.w3.org/1999/xlink"
name="href" >jmilton.html</xsl:attribute>
John Milton
</xsl:element>
<xsl:element name="img"
namespace= "http://www.w3.org/TR/REC-html40">
<xsl:attribute name="src">milton.jpg</xsl:attribute>
</xsl:element>
<xsl:apply-templates/>
</section>
</xsl:template>
When applied to the same source document as the earlier examples, this stylesheet creates a result document that has an author element with two attributes from the XLink namespace and an img element from the HTML namespace. The XSLT processor can make up any namespace prefixes it wants; in this case, they're "ns0" and "ns1".
<section>
<author xmlns:ns0= "http://www.w3.org/1999/xlink"
ns0:type="simple" ns0:href="jmilton.html">
John Milton
</author>
<ns1:img xmlns:ns1= "http://www.w3.org/TR/REC-html40"
src="milton.jpg"/>
With Opal Towers and Battlements adorned</section>
To review: the XSLT processor looks through a stylesheet for elements belonging to the XSLT namespace and executes their instructions, and for any elements outside of that namespace (that aren't from a namespace declared for extension elements), it passes them along to the result with namespace declarations if necessary. You can even assign a specific namespace for an element or attribute by adding a namespace attribute to an xsl:element or xsl:attribute element.