Another area of interest is namespace aliasing. This is a feature that allows you to use one namespace in the stylesheet and then swap it with another in the result tree. This is done with the namespace-alias element.
The namespace-alias element may appear on the top level of a stylesheet. It has two attributes: stylesheet-prefix, which contains a prefix associated with a namespace in the stylesheet, and result-prefix, which holds a prefix also declared in the stylesheet but to be output in the result tree. If you want to refer to a default namespace declaration instead of a prefix, you can use #default as a value for either of these attributes. All this will make more sense with a practical example. The stylesheet alias.xsl uses the namespace-alias element: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="urn:wyeast-net:scandinavia" xmlns:sc="http://www.wyeast.net/scand"> <xsl:output method="xml" indent="yes" encoding="ISO-8859-1"/> <xsl:namespace-alias stylesheet-prefix="sc" result-prefix="#default"/> <xsl:template match="europe"> <xsl:apply-templates select="scandinavia"/> </xsl:template> <xsl:template match="scandinavia"> <sc:scandinavia> <xsl:apply-templates select="state"> <xsl:sort/> </xsl:apply-templates> </sc:scandinavia> </xsl:template> <xsl:template match="state"> <sc:country><xsl:value-of select="."/></sc:country> </xsl:template> </xsl:stylesheet> The stylesheet produces XML. The literal result elements in the templates are prefixed with sc, which is associated with the namespace URI http://www.wyeast.net/scand. A default namespace is also declared using the URN urn:wyeast-net:scandanavia, but it isn't used in the stylesheet it's intended for use in the result. To demonstrate how this process works, apply alias.xml to scand.xml with MSXSL: msxsl scand.xml alias.xsl Here is the output from this transformation: <?xml version="1.0" encoding="ISO-8859-1"?> <scandinavia xmlns="urn:wyeast-net:scandinavia"> <country>Denmark</country> <country>Finland</country> <country>Iceland</country> <country>Norway</country> <country>Sweden</country> </scandinavia> With MSXSL, the sc prefix is dropped in the resulting elements. The default namespace urn:wyeast-net:scandinavia is used instead of the namespace associated with the sc prefix, that is, http://www.wyeast.net/scand. This is what I expected a processor to do, having read the spec on the issue (Section 7.1.1). Now, if you perform the same transformation with Xalan: xalan scand.xml alias.xsl you get a different result: <sc:scandinavia xmlns="urn:wyeast-net:scandinavia" xmlns:sc="urn:wyeast-net:scandinavia"> <sc:country>Denmark</sc:country> <sc:country>Finland</sc:country> <sc:country>Iceland</sc:country> <sc:country>Norway</sc:country> <sc:country>Sweden</sc:country> </sc:scandinavia> With Xalan, the prefix is retained in the output. The main difference is that the default namespace in the stylesheet is now associated with the prefix sc. Frankly, the MSXSL interpretation seems more logical to me, but the functionality displayed by Xalan and other processors like Saxon appear to be the norm.
The most common reason to use namespace-alias is probably to create XSLT elements in the result tree. Without aliasing, any XSLT element will be interpreted as just that, an XSLT element. Sometimes, you just want to create XSLT elements in the result tree, and namespace aliasing will let you do it. You can see how this works in Example 14-2, which shows the stylesheet xslt.xsl. Example 14-2. A stylesheet using namespace aliasing<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="urn:wyeast-net:scandanavia" xmlns:sc="http://www.wyeast.net/scand" xmlns:t="http://www.wyeast.net/temp"> <xsl:output method="xml" indent="yes" encoding="ISO-8859-1"/> <xsl:namespace-alias stylesheet-prefix="t" result-prefix="xsl"/> <xsl:template match="europe"> <t:stylesheet version="1.0"> <t:output method="xml" indent="yes" encoding="ISO-8859-1"/> <t:namespace-alias stylesheet-prefix="sc" result-prefix="#default"/> <xsl:text> </xsl:text> <t:template match="{name( )}"> <t:apply-templates select="scandinavia"/> </t:template> <xsl:text> </xsl:text> <xsl:apply-templates select="scandinavia"/> <xsl:apply-templates select="scandinavia/state[1]"/> <xsl:text> </xsl:text> </t:stylesheet> </xsl:template> <xsl:template match="scandinavia"> <xsl:text> </xsl:text> <t:template match="{name( )}"> <sc:scandinavia> <t:apply-templates select="state"> <t:sort/> </t:apply-templates> </sc:scandinavia> </t:template> <xsl:text> </xsl:text> </xsl:template> <xsl:template match="state"> <xsl:text> </xsl:text> <t:template match="{name( )}"> <sc:country> <t:value-of select="."/> </sc:country> </t:template> <xsl:text> </xsl:text> </xsl:template> </xsl:stylesheet> Now apply it to scand.xml with MSXSL: msxsl -o newalias.xsl scand.xml xslt.xsl When you look at newalias.xsl, you will see the following output, which is nearly identical to alias.xsl: <?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns="urn:wyeast-net:scandanavia" xmlns:sc=" http://www.wyeast.net/scand" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" encoding="ISO-8859-1" /> <xsl:namespace-alias stylesheet-prefix="sc" result-prefix="#default" /> <xsl:template match="europe"> <xsl:apply-templates select="scandinavia" /> </xsl:template> <xsl:template match="scandinavia"> <sc:scandinavia> <xsl:apply-templates select="state"> <xsl:sort /> </xsl:apply-templates> </sc:scandinavia> </xsl:template> <xsl:template match="state"> <sc:country> <xsl:value-of select="." /> </sc:country> </xsl:template> </xsl:stylesheet> The stylesheet effectively scanned the document and created a new stylesheet based on what it found. To complete the circle, now transform scand.xml with newalias.xsl: msxsl scand.xml newalias.xsl You'll get the same result you got with alias.xsl: <?xml version="1.0" encoding="ISO-8859-1"?> <scandinavia xmlns="urn:wyeast-net:scandanavia"> <country>Denmark</country> <country>Finland</country> <country>Iceland</country> <country>Norway</country> <country>Sweden</country> </scandinavia> Namespace aliasing, as you can see, is useful when you want to create new stylesheets from your old stylesheets. |