RE: [xsl] updated namespace difficulty

Subject: RE: [xsl] updated namespace difficulty
From: "Roger Glover" <glover_roger@xxxxxxxxx>
Date: Sun, 16 Feb 2003 01:45:48 -0600
Hi Simon,

S Woodside wrote:
> the output of the 1st transform contains lots of stuff, including
>              <form_textarea xmlns="mynms"><b>foobar</b></form_textarea>
> the second xslt is this (complete):
> <?xml version="1.0"?>
> <xsl:stylesheet
>    xmlns="foo"
>    xmlns:my="mynms"
>    xmlns:xsl="";
>    version="1.0"
>    >
>    <xsl:template match="my:form_textarea" priority="1">
>      <b>SIMONHELLO</b>
>    </xsl:template>
> <!--
>    [[xsl:template match="*" priority="-1"]]
>      [[xsl:copy-of select="."/]]
>    [[/xsl:template]]
> -->
> </xsl:stylesheet>
> As is, it gives me this in the output, among other things:
>              <b xmlns="foo" xmlns:my="mynms">SIMONHELLO</b>
> which is AFAICT correct. However I also want to copy through the rest
> of the output from the 1st transform! How do I do that? If I uncomment
> the 2nd template in the 2nd xslt, instead I get:
>              <form_textarea xmlns="mynms"><b>foobar</b></form_textarea>

That is because <xsl:copy-of> does not apply templates to child nodes of the
context node.  It just recursively and blindly deep-copies the context node
and its children.  What you want instead is some variation of the classic
"copy template" (with or without the lowered priority).  This template is
immortalized in the FAQ, in the spec, in numerous postings to this mail
list, and in a major motion picture coming soon from "&#xA; Pictures":
"Node of the Root:  The Two Templates".

Instead of your commented-out template, try this one:

<xsl:template match="*|@*">
        <xsl:apply-templates select="*|@*"/>

This copy template by default performs a deep copy of the context node, but
unlike your template, it does so by applying itself to its own child nodes
until the node tree runs out of depth.  Also, because of the dynamic binding
between <xsl:apply-templates> and <xsl:template>, the processor will select
your first template, rather than itself when it finds the child element that
matches that template.

The difference between this and using <xsl:copy-of> is that <xsl:copy-of>
does not bind to any templates at all.  With <xsl:copy-of> there is no
recursive descent through the node tree (by templates).  Thus, there is no
opportunity to override the generic match of the first template with the
specific match of the second.  So with your second template, containing
<xsl:copy-of>, your output contains an exact copy of the input, rather than
the near-copy-with-specific-node-replacement for which you are aiming with
your first template.

-- Roger

 XSL-List info and archive:

Current Thread