Dieter Menne
Dieter Menne

Reputation: 10205

XSLT: How to call user-defined function given as string

I have to use XSLT 1.0 with the XML below. It has a function jr:itext which I have surrogated by a user-defined function with exslt. I could strip jr:itext() and call the function explicitly as shown in the example, but it looks ugly and I have other functions in the full version.

How do I call(func-string) in XSLT`?

<?xml version="1.0"?>
<html xmlns="http://www.w3.org/2002/xforms" xmlns:jr="http://openrosa.org/javarosa">
  <label ref="jr:itext('calculate_test_output')"/>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     xmlns:jr="http://openrosa.org/javarosa" 
   xmlns:func="http://exslt.org/functions"
     extension-element-prefixes="func" >

    <func:function name="jr:itext">
      <xsl:param name="ref" />
        <func:result select="concat('itext ', $ref)"/>
    </func:function>


    <xsl:template match="/">
       Requested output
      <xsl:value-of select="jr:itext('calculate_test_output')" />,

    Using "call function from string?"
        <xsl:variable name="ref" select="html/label/@ref"/>
        <xsl:value-of select="$ref"/>
<!--      <xsl:execute-this-function select="$ref" />,-->
   
    </xsl:template>

</xsl:stylesheet>

Upvotes: 0

Views: 600

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167401

Using xsltproc (xsltproc was compiled against libxml 20910, libxslt 10134 and libexslt 820) it works for me to use the EXSLT dyn:evaluate function to call both XPath 1.0 functions as well as func:function defined functions dynamically:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:jr="http://openrosa.org/javarosa" xmlns:func="http://exslt.org/functions"
    extension-element-prefixes="func">

    <func:function name="jr:itext">
        <xsl:param name="ref"/>
        <func:result select="concat('itext ', $ref)"/>
    </func:function>

    <xsl:template match="label">
        <xsl:copy>
            <xsl:value-of select="dyn:evaluate(@ref)" xmlns:dyn="http://exslt.org/dynamic"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

when run against (for simplicity of the example I used the elements in no namespace)

<html  xmlns:jr="http://openrosa.org/javarosa">
    <label ref="jr:itext('calculate_test_output')"/>
    <label ref="concat('test', ' 1')"/>
</html>

outputs

<label>itext calculate_test_output</label>
<label>test 1</label>

Upvotes: 2

Related Questions