Changing Namespace Aliases Programmatically

MSXML 5.0 SDK

Microsoft XML Core Services (MSXML) 5.0 for Microsoft Office - XSLT Developer's Guide

Changing Namespace Aliases Programmatically

Suppose you want to use an XSLT style sheet to produce another XSLT style sheet. In such an application, you will have to deal with two kinds of XSLT elements. One set of elements consists of the XSLT instructions that tell the XSLT processor to perform the transformation. The other set consists of the XSLT elements that will be output. These elements are the literal result elements. During the transformation, you will have to use different namespaces for these two types of elements.

The following is a simple example.

  <xsl:stylesheet version="1.0"
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
       <xsl:output method="xml"/>
       <xsl:template match="text()">
           <xsl:value-of select="."/>
       </xsl:template>
       <xsl:template match="/">Template for root mapped.</xsl:template>
  </xsl:stylesheet>

We cannot put this inside a template rule, like this:

<xsl:template match="/">
  <!-- We can't put the above literal results elements here. -->
</xsl:template>

An <xsl:stylesheet> element cannot be a child of any XSLT element. The solution to this problem is to treat the two sets of XSLT elements as belonging to different namespaces during the transformation. Use the regular XSLT namespace for the XSLT instruction elements, and use a temporary namespace for the literal result elements. At the end of the transformation, change the output elements from the temporary namespace to the regular XSLT namespace.

An XSLT Style Sheet Can Generate another XSLT Style Sheet

The following style sheet generates another style sheet.

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="simple.xsl"?>
<!-- Declare two namespaces: "xsl" is for XSLT instructions,
    and "out" is for literal result elements, 
    temporarily. -->
<xsl:stylesheet version="1.0"    
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:out="transform.xsl">
<xsl:output method="xml" indent="yes"/>

<!-- The following intruction switches the result element's 
     namespace from "out" to "xsl". -->
<xsl:namespace-alias stylesheet-prefix="out" result-prefix="xsl"/>

<xsl:template match="/">
  <out:stylesheet>
       <out:output method="xml"/>
       <out:template match="text()">
           <out:value-of select="."/>
       </out:template>
       <out:template match="/">Template for root mapped.</out:template>
  </out:stylesheet>
</xsl:template>

</xsl:stylesheet>

The use of the temporary namespace (xmlns:out="temporary.xsl") prevents the XSLT processor from processing the output XSLT elements. It is important that both the namespace prefix and the URI differ for the result and instruction elements. The <xsl:namespace-alias> element re-maps the namespace from out to xsl (including the corresponding URIs) on the result elements.

Output XSLT Style Sheet

The following is the output of this XSLT transformation.

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml"/>
   <xsl:template match="text()">
      <xsl:value-of select="."/>
   </xsl:template>
   <xsl:template match="/">Template for root mapped</xsl:template>
</xsl:stylesheet>