1
<xsl:template match="foobar">
    <xsl:if test="a[name = 'foo']">
        <xsl:apply-templates select="x/y[1]|x/y[2]" />
    </xsl:if>
    <xsl:if test="a[name = 'bar']">
        <xsl:apply-templates select="x/y[3]|x/y[4]|x/y[5]" />
    </xsl:if>
</xsl:template>

I would like to pass the location path expressions "x/y[1]|x/y[2]" and x/y[3]|x/y[4]|x/y[5] as parameter because this values may change in the future and I don't want to edit the template but only the parameter definition. I would like to use the template above as

<xsl:template match="foobar">
    <xsl:if test="a[name = 'foo']">
        <xsl:apply-templates select="$param1" />
    </xsl:if>
    <xsl:if test="a[name = 'bar']">
        <xsl:apply-templates select="$param2" />
    </xsl:if>
</xsl:template>

As far as I know this is not possible. What is the best way to externalize the location path expressions?

Many thanks in advance

Toru
  • 905
  • 1
  • 9
  • 28
  • 1
    Dynamic evaluation isn't available in both XSLT 1.0 and XSLT 2.0. It may be available in XSLT 3.0 (now having the status of working draft). One way to overcome this obstcle is to have a transformation that generates a new stylesheet based on its source XML document(s) -- then execute the newly-generated transformation. – Dimitre Novatchev Sep 29 '12 at 20:10
  • 1
    Many thanks for the hint. The generation of a new stylesheet is an option. – Toru Sep 30 '12 at 19:21

2 Answers2

1
<xsl:template match="foobar">
    <xsl:param name="param1" />
    <xsl:param name="param2" />
    <xsl:if test="a[name = 'foo']">
        <xsl:apply-templates select="$param1" />
    </xsl:if>
    <xsl:if test="a[name = 'bar']">
        <xsl:apply-templates select="$param2" />
    </xsl:if>
</xsl:template>

and then you call the template with:

<xsl:call-template name="foobar">
    <xsl:with-param name="param1" select="actualXPath1"/>
    <xsl:with-param name="param2" select="actualXPath2"/>
</xsl:call-template>

or you can use global parameters in the beginning of the XSLT file.

<xsl:param name="param1" select="actualXPath1"/>
<xsl:param name="param2" select="actualXPath2"/>
<!-- continue with template definitions -->
...

This article may help.

Jiri Kremser
  • 12,471
  • 7
  • 45
  • 72
  • The usage of template parameters was not the problem. But the usage of template parameters **in relation with XPath expressions**. And your example doesn't work with XPath expressions. – Toru Sep 30 '12 at 19:29
  • You're right. And can't you just parametrize the "test" attribute instead of the "select"? It should be possible http://stackoverflow.com/questions/2250604/how-to-use-a-parameter-in-a-xslt-as-a-xpath – Jiri Kremser Sep 30 '12 at 22:12
0

If you don't mind using proprietary functions or EXSLT, you can dynamically evaluate an XPath expression available as a string:

  • EXSLT's dyn:evaluate(string)
  • Saxon 6.5.5 and 9.x also have a proprietary evaluate(string) function.

Then, you can pass these XPath strings as global parameters to your XSLT, or store them in an external file, for instance.

bmaisonny
  • 16
  • 1