Microsoft XML 2.5 SDK


 

Copying Entire Subtrees

[This is preliminary documentation and subject to change.]

Often a fragment of a foreign grammar is to be encapsulated in another. In the following example, the "logo" element contains arbitrary well-formed HTML. When transforming this data to HTML, the contents of the "logo" element should be copied directly to the output.

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="portfolio2.xsl"?>
<portfolio xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <stock exchange="nyse">
    <name>zacx corp</name>
    <symbol>ZCXM</symbol>
    <price dt:dt="number">28.875</price>
    <logo>
      <A href="http://www.zacx-corp.com">
        <IMG src="zacxcorp.gif"/>
      </A>
    </logo>
  </stock>
  <stock exchange="nasdaq">
    <name>zaffymat inc</name>
    <symbol>ZFFX</symbol>
    <price dt:dt="number">92.250</price>
    <logo><P STYLE="font:italic 14pt 'Arial Black'">zaffymat</P></logo>
  </stock>
</portfolio>

The identity transformation introduced in Filtering XML can be used locally to copy the logo subtree from the source document to the result tree. Defining a limited scope for the template will prevent the identity transform from applying outside the subtree. The scope is defined by placing the identity transform template within the <xsl:apply-templates> element, indicating that the elements selected thereby are to be processed with this specific template. For more details on scoping, see Scoping Templates.

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
  <xsl:template match="/">
    <HTML>
      <BODY>
        <xsl:for-each select="portfolio/stock">
          <DIV STYLE="font-size:smaller">Symbol: <xsl:value-of select="symbol"/>,
            Company: <xsl:value-of select="name"/>,
            Price: $<xsl:value-of select="price"/>
          </DIV>
          <DIV>
            <!-- select the children of the logo element -->
            <xsl:apply-templates select="logo/*">
              <!-- recursively apply this template to them -->
              <xsl:template>
                <xsl:copy>
                  <xsl:apply-templates select="@* | * | comment() | pi() | text()"/>
                </xsl:copy>
              </xsl:template>
            </xsl:apply-templates>
          </DIV>
          <HR/>
        </xsl:for-each>
      </BODY>
    </HTML>
  </xsl:template>
</xsl:stylesheet>

The element children of the "logo" element are processed by the identity transformation, copying this entire subtree to the output, so the embedded HTML appears in the output.