0

So I'm using the identity design pattern for XSLT:

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()[not(@visible='false')]"/>
  </xsl:copy>
</xsl:template>

And I do have many templates matching different nodes. Now what I want to do is generate some code inside one xsl:template and let another xsl:template match the newly generated code. Anyone who have any idea how to do this?


Example of what I want to do:

<xsl:template match="button">
     <a href="@url" class="button"> <xsl:value-of select="@name" /> </a>
</xsl:template>

<xsl:template match="stuff">
    <!-- do some stuff -->
    <!-- get this following line parsed by the template over! -->
    <button url="something" name="a button" />
</xsl:template>
Knarf
  • 1,282
  • 3
  • 12
  • 31
  • Because I want to add a button but let the button creating part of the script create the actual button markup. – Knarf May 08 '12 at 19:36

2 Answers2

3

You can't do quite what you want to do in the way you are trying, however if the intention is to re-use code and avoid duplicate templates, it is perfectly acceptable for a matching template to be called as a named template, with parameters too.

<xsl:template match="button" name="button"> 
   <xsl:param name="url" select="@url" />
   <xsl:param name="name" select="@name" />
   <a href="{$url}" class="button"> <xsl:value-of select="$name" /> </a> 
</xsl:template> 

So, here if it is matching a button element, it will use the url and name attributes as the default values, but if you call it as a named-template, you can pass in your own parameters

<xsl:template match="stuff"> 
   <!-- do some stuff --> 
   <!-- get this following line parsed by the template over! --> 
   <xsl:call-template name="button">
    <xsl:with-param name="url" select="'something'" /> 
    <xsl:with-param name="name" select="'A button'" /> 
   </xsl:call-template> 
</xsl:template> 
Tim C
  • 70,053
  • 14
  • 74
  • 93
1

You should be able to do some multi-pass processing using the node-set() extension function.

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:template match="/*">
    <xsl:variable name="first_pass">
      <xsl:apply-templates select="button" />
    </xsl:variable>

    <xsl:apply-templates mode="second_pass" select="ext:node-set($first_pass)/*" />
  </xsl:template>

  <xsl:template match="button">
    <a href="@url" class="button"> <xsl:value-of select="@name" /> </a>
  </xsl:template>

  <xsl:template match="stuff" mode="second_pass">
    <!-- do some stuff -->
    <!-- get this following line parsed by the template over! -->
    <button url="something" name="a button" />
  </xsl:template>
</xsl:stylesheet>

You can get more details in the first answer of XSLT - apply a template to call-template result .

Community
  • 1
  • 1
Eric
  • 2,784
  • 1
  • 20
  • 25