1

Is there a way I can check my variable in the select attribute and call one of two user functions TestFx or TestFx2. Now I know I can use xsl:if or xsl:choose, but was just wondering if there was another way.

For example select="$hasTextArea=true ? TestFx : TestFx2"

<xsl:variable name="hasTextArea">true</xsl:variable>

<xsl:template name="break">
    <xsl:param name="text" select="."/>
    <xsl:value-of disable-output-escaping="yes" select="user:TestFx($text)" />
</xsl:template>
Rod
  • 14,529
  • 31
  • 118
  • 230

2 Answers2

1

XSLT 1.0 does not have a ternary operator. Just use <xsl:if> or <xsl:choose> and spend your time on something more worthwhile than trying to find a clever hack. (You can do this, if you really must.)

XSLT 2.0 (i.e. XPath 2.0) has this:

<xsl:value-of select="
  if ($hasTextArea = 'true') 
    then user:TestFx($text) 
    else user:TestFx2($text)
" />
Community
  • 1
  • 1
Tomalak
  • 332,285
  • 67
  • 532
  • 628
0

Is there a way I can check my variable in the select attribute and call one of two user functions TestFx or TestFx2. Now I know I can use xsl:if or xsl:choose, but was just wondering if there was another way.

Here is a complete demo how to do this. This illustrates the basic principle how to implement higher-order functions in XSLT 1.0 and 2.0 -- used in the FXSL library for functional programming with XSLT.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="my:user" xmlns:my="my:my">
 <xsl:output method="text"/>

 <my:functions>
   <my:F1/>
   <my:F2/>
 </my:functions>

 <xsl:variable name="vMyFuncs" select="document('')/*/my:functions/*"/>

 <xsl:param name="phasTextArea" select="true()"/>
 <xsl:param name="pText" select="'Some Text'"/>

 <xsl:template match="/*">
    <xsl:variable name="vFunc" select=
      "$vMyFuncs[1][$phasTextArea] | $vMyFuncs[2][not($phasTextArea)]"/>

  <xsl:apply-templates select="$vFunc"/>
 </xsl:template>

 <xsl:template match="my:F1">
  <xsl:value-of select="user:TestFx($pText)"/>
 </xsl:template>

 <xsl:template match="my:F2">
  <xsl:value-of select="user:TestFx2($pText)"/>
 </xsl:template>

 <msxsl:script language = "c#"  implements-prefix = "user">
  public string TestFx(string text)
  {
    return "Text is: " + "'" +text + "'";
  }

  public string TestFx2(string text)
  {
    return string.Format("Text length is: {0}", text.Length);
  }
</msxsl:script>
</xsl:stylesheet>

When this transformation is applied on any XML document (not used), the wanted correct result (user:TestFx() called) is produced:

Text is: 'Some Text'

If we modify the code above by setting the $phasTextArea to false(), the result now shows that this time user:TestFx2() has been called:

Text length is: 9

And, as promised, the transformation has no explicit XSLT conditional instructions (xsl:choose or xsl:if).

Also, we don't count characters to do unnecessary tricks with substring().

Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431