26

Please explain me how best XSLT param can be used. in terms of <xsl:param> & <xsl:with-param>

Sample LOC:

<xsl:call-template name="ABC">
    <xsl:with-param name="title" />
</xsl:call-template>
Siva Charan
  • 17,940
  • 9
  • 60
  • 95
  • 2
    Good question, +1. While I give a detailed explanation of `xsl:param` and `xsl:with-param` in my answer, I would recommend that you read a good book on XSLT. Practice is absolutely necessary in order to come with good grip of this concept. – Dimitre Novatchev Sep 11 '11 at 15:28

2 Answers2

40

Please explain me how best XSLT param can be used. in terms of <xsl:param> & <xsl:with-param>

<xsl:param> can be specified at the global level anywhere (as a child of xsl:stylesheet) or if it is within a template, it must be its child and it must precede any non-xsl:param child of xsl:template.

This is the facility that allows a template or the whole transformation (in case of a global xsl:param) to receive varying data from the caller/initiator of the template or of the whole transformation, respectively.

On the side of the caller/initiator of the template/transformation, parameters are passed by using an xsl:with-param instruction. it can be a child of xsl:apply-templates or xsl:call-template.

The name attribute of either xsl:param or xsl:with-param is mandatory. It identifies the parameter.

The select attribute of xsl:with-param may be used to specify any XPath expression, the result of whose evaluation is passed to the called/applied template.

Alternatively, the value can be specified in the content (body) of xsl:with-param.

xsl:with-param must have either a select attribute or a body. but not both of them.

An xsl:param can also have a select attribute or body. In this case, these specify the default value of the parameter and it is used if no parameter with this name has been specified by the caller.

Finally, here is a complete example illustrating most of these concepts:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pTarget" select="'love'"/>
 <xsl:param name="pReplacement" select="'like'"/>

 <xsl:template match="/*">
  <xsl:call-template name="replace">
   <xsl:with-param name="pPattern" select="$pTarget"/>
   <xsl:with-param name="pRep" select="$pReplacement"/>
  </xsl:call-template>

  <xsl:text>&#xA;</xsl:text>

  <xsl:call-template name="replace"/>

  <xsl:text>&#xA;</xsl:text>

  <xsl:apply-templates select="text()">
   <xsl:with-param name="pPattern" select="$pTarget"/>
   <xsl:with-param name="pRep" select="'adore'"/>
  </xsl:apply-templates>
 </xsl:template>

 <xsl:template match="text()" name="replace">
   <xsl:param name="pText" select="."/>
   <xsl:param name="pPattern" select="'hate'"/>
   <xsl:param name="pRep" select="'disapprove'"/>

   <xsl:if test="string-length($pText) >0">
       <xsl:choose>
        <xsl:when test="not(contains($pText, $pPattern))">
          <xsl:value-of select="$pText"/>
        </xsl:when>
        <xsl:otherwise>
         <xsl:value-of select="substring-before($pText, $pPattern)"/>
         <xsl:value-of select="$pRep"/>

         <xsl:call-template name="replace">
           <xsl:with-param name="pPattern" select="$pPattern"/>
           <xsl:with-param name="pRep" select="$pRep"/>
           <xsl:with-param name="pText" select=
            "substring-after($pText, $pPattern)"/>
         </xsl:call-template>
        </xsl:otherwise>
       </xsl:choose>
   </xsl:if>
 </xsl:template>
</xsl:stylesheet>

When applied on this XML document...

<t>Sports stars we really love, love to hate, hate</t>

...the result is...

Sports stars we really like, like to hate, hate
Sports stars we really love, love to disapprove, disapprove
Sports stars we really adore, adore to hate, hate

Explanation:

  1. The replace template is called twice. In both calls the pText parameter is omitted. Its default value is used by the called template.

  2. The first call provides the pattern and replacement parameters, so "love" is replaced by "like".

  3. Do note that the values of the global parameters $pTarget and $pReplacement are passed through. If the initiator of the transformation decides to pass other values (not the defaults that are used in this code) for these global parameters, these values will be passed to the replace template and not the defaults "love" and "like".

  4. The second call doesn't provide any parameter values at all, so all defaults in the replace template are used -- the string "hate" is replaced by the string "disapprove".

  5. Note that the replace template calls itself recursively, so that all occurrences of the pattern are replaced by the replacement.

  6. Also, the values of the pText parameter of the recursive calls aren't static, but are dynamically calculated.

  7. The third time the replace template is initiated from outside is via xsl:apply-templates. Here we also show that a template can have both a match and a name attribute at the same time and it is possible that such a template can be initiated both using xsl:apply-templates and xsl:call-template.

w5m
  • 2,286
  • 3
  • 34
  • 46
Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
  • That's perfect answer Dimitre. Thanks for explaning the answer in more detailed way. I have small query, `` & `` should be used in between `` & `` or we can use either one. If yes, which is the best one between this two templates (`` & ``) & which is the more efficient one in using? – Siva Charan Sep 12 '11 at 04:29
  • @Siva Charan: `xsl:param` is used only as a global parameter or as a child of `xsl:template` . With both `xsl:apply-templates` and `xsl:call-templates` the *only* way to specify passing of parameters is via `xsl:with-param` – Dimitre Novatchev Sep 12 '11 at 04:33
10

It's used to pass a param defined in another template:

<xsl:param name="globalParam"></xsl:param>

<xsl:call-template name="ABC">
  <xsl:with-param name="title" select="'A Title'" />
</xsl:call-template>

<xsl:template name="ABC">
  <xsl:param name="title"/>
  <xsl:value-of select="$title" />
  <xsl:value-of select="$globalParam" />
</xsl:template>
altocumulus
  • 21,179
  • 13
  • 61
  • 84
TheCodeKing
  • 19,064
  • 3
  • 47
  • 70
  • Thanks for the reply. **'A Title'** is a static value. right? if yes, can we pass a static value in XSLT. please explain some more info in detailed way... – Siva Charan Sep 11 '11 at 14:41
  • The param can be a static value or a match expression. If you want to pass in a param define it in the outer scope. You can then set it when you preform the transform. – TheCodeKing Sep 11 '11 at 14:49
  • Actually, as shown in my answer, a template may pass an `xsl:param` *to itself* in a recursive call. Therefore the statement "It's used to pass a param defined in another template", isn't completely correct. – Dimitre Novatchev Sep 11 '11 at 17:17
  • 2
    It's correct in the context of the question, I think that's being a bit picky on the wording – TheCodeKing Sep 11 '11 at 17:34