Re: Recursive Templates

Subject: Re: Recursive Templates
From: Michael Stillwell <mjs@xxxxxxxxx>
Date: Mon, 2 Aug 1999 10:58:09 +1000 (EST)
Tony Graham <tgraham@xxxxxxxxxxxxxxxx> wrote:
: At 2 Aug 1999 03:12 +1000, Michael Stillwell wrote:
:  > I've just started using XSL and am wondering how to achieve the
:  > transformation such as the following.  I want to transform
:  > 
:  >   <section>Introduction</section>
:  >   
:  > into (say)
:  > 
:  >   <caps><strong>Introduction</strong></caps>
:  >
:  > My first attempt used templates like
:  > 
:  >   <xsl:template match="emph" name="emph">
:  >   <strong>
:  >   <xsl:apply-templates/>
:  >   </strong>
:  >   </xsl:template>
:  > 
:  >   <xsl:template match="section">
:  >   <caps>
:  >   <emph>
:  >   <xsl:apply-templates/>
:  >   </emph>
:  >   </caps>
:  >   </xsl:template>
:  > 
:  > Unfortunately, the <emph> ... </emph> tags produced but the "section"
:  > template are not transformed into <strong> ... </strong> tags.  I
:  > more or less understand why this is, but the best set of templates I
:  > have found that do what I want are
: 
: You appear to be confusing the source tree and the result tree.  When
: it's time to process a particular node in the source tree, the XSL
: processor finds the xsl:template with the best matching "match"
: attribute and uses the body of that xsl:template to add (or not add)
: nodes to the result tree.  The <emph> in your xsl:template is added to
: the result tree, and that's all that happens to it.  It doesn't get
: any templates applied to it.

I guess I didn't explain myself very well.  My actual problem is
"topologically" identical to the problem I presented, but involves
more elaborate transformations.  In particular, I want some of the
text that is transformed by the "strong" template to come from the
"caps" template, and some from the source tree.  e.g transforming

  <section>Introduction</section>
  
into  

  <caps><emph>[Introduction]</emph></caps>

This could be accomplished with a recursive rule like

  <xsl:template match="section">
    <caps>
      <strong>
        [<xsl:apply-templates/>]
      </strong>
    </caps>
  </xsl:template>

But recursive rules don't work!  I don't think the templates suggested
below can easily be modified to handle this case; the only way I know
of doing this involves the passing parameters to a template mechanism.

(I want the "strong" to "emph" transformation to be a separate rule
because in my case, much more text is involved, because I want to
apply the transformation in more than one place, etc.)


Michael

:  >   <xsl:template match="emph" name="emph">
:  >   <strong>
:  >   <xsl:copy-of select="$content"/>
:  >   </strong>
:  >   </xsl:template>
:  > 
:  >   <xsl:template match="section">
:  >   <caps>
:  >   <xsl:call-template name="emph">
:  >     <xsl:with-param name="content">
:  >       <xsl:apply-templates/>
:  >     </xsl:with-param>
:  >   </xsl:call-template>  
:  >   </caps>
:  >   </xsl:template>
: 
: There are many better ways.  I gave a version earlier with a single
: xsl:template.  If you really want to do it with multiple xsl:template
: elements, try:
: 
: <xsl:template match="emph" name="emph">
:   <strong>
:     <xsl:apply-templates/>
:   </strong>
: </xsl:template>
: 
: <xsl:template match="section">
:   <caps>
:     <xsl:call-template name="emph"/>
:   </caps>
: </xsl:template>

-- 
:::: mjs@xxxxxxxxx ::::::::::::::::::::::::::::: http://beebo.org ::::
:::: mjs@xxxxxxxxx ::::::::::::::::::::::::::::: http://beebo.org ::::
:::: mjs@xxxxxxxxx ::::::::::::::::::::::::::::: http://beebo.org ::::


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread