首页 > 解决方案 > XSLT:如何调用以字符串形式给出的用户定义函数

问题描述

我必须将 XSLT 1.0 与下面的 XML 一起使用。它有一个功能jr:itext,我已经用exslt. jr:itext()如示例所示,我可以显式剥离并调用该函数,但它看起来很难看,而且我在完整版中有其他函数。

我如何call(func-string)在 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>

标签: xmlxsltxslt-1.0

解决方案


使用 xsltproc(xsltproc 是针对 libxml 20910、libxslt 10134 和 libexslt 820 编译的)我可以使用 EXSLTdyn:evaluate函数来动态调用 XPath 1.0 函数和func:function定义的函数:

<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>

运行时(为简单起见,我使用了无命名空间中的元素)

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

输出

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

推荐阅读