示例:
<xsl:function name="my:function" as="xs:integer">
<xsl:param name="pNum" as="xs:integer" />
<xsl:sequence select="$pNum * 2" />
</xsl:function>
<xsl:sequence select="my:function(1)" />
我希望能够调用my:function
,如果可能,请保留对此函数的引用。
下面的代码不能工作,但是想表明我想要做的事情:
<xsl:variable name="vFn" select="my:function" />
<xsl:sequence select="$vFn(5)" />
我正在对明文格式的纯文本文件进行转换,将其转换为html。我不确定它是否使我在xml文档上运行的事情变得复杂。
答案 0 :(得分:4)
对于来到这里的其他人可能感兴趣:Dimitre Novatchev设计了一种在XSLT 2.0中工作的方法(或者如果用命名模板代替函数,即使在1.0中,也使用节点集扩展)。 (他还创建了一个名为FXSL的库,利用该技术)。
创建一个包含以函数命名的元素的变量:
<xsl:variable name="my:function" as="element()">
<my:function/>
</xsl:variable>
然后创建一个匹配此元素的模板规则并调用函数:
<xsl:template mode="dyn" match="my:function">
<xsl:param name="p1"/>
<xsl:sequence select="my:function($p1)"/>
</xsl:template>
现在定义一个动态调用函数:
<xsl:function name="dyn:call">
<xsl:param name="function"/>
<xsl:param name="param"/>
<xsl:apply-templates select="$function" mode="dyn">
<xsl:with-param name="p1" select="$param"/>
</xsl:apply-templates>
</xsl:function>
现在您可以使用变量$my:function
作为函数的代理,将其作为
... select="dyn:call($my:function, 2)"/>
答案 1 :(得分:2)
可以在使用<xsl:variable name="vFn" select="my:function#1"/>
的XSLT 3.0中查看https://www.w3.org/TR/xpath-30/#id-dynamic-function-invocation和https://www.w3.org/TR/xpath-30/#id-named-function-ref。
答案 2 :(得分:2)
<强>予。这是一个XSLT 1.0示例,我在FXSL中使用的技术:
<xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f1="8B9C63F4-F4AB5D11-994A0001-B4CD626F"
xmlns:f2="AB02AC1C-1C65B3FF-77C5FFFE-4B329DA1" >
<f1:f1/>
<f2:f2/>
<xsl:variable name = "vFun1" select = "document('')/*/f1:*[1]" />
<xsl:variable name = "vFun2" select = "document('')/*/f2:*[1]" />
<xsl:template match="f1:*">
<xsl:param name = "pX" />
<xsl:value-of select = "2 * $pX" />
</xsl:template>
<xsl:template match="f2:*">
<xsl:param name = "pX" />
<xsl:value-of select = "3 * $pX" />
</xsl:template>
<xsl:template match = "/">
<xsl:call-template name = "mySum" >
<xsl:with-param name = "pX" select = "3" />
<xsl:with-param name = "pFun1" select = "$vFun1" />
<xsl:with-param name = "pFun2" select = "$vFun2" />
</xsl:call-template>
</xsl:template>
<xsl:template name = "mySum" >
<xsl:param name = "pX" />
<xsl:param name = "pFun1" select = "/.." />
<xsl:param name = "pFun2" select = "/.." />
<xsl:variable name = "vFx_1" >
<xsl:apply-templates select = "$pFun1" >
<xsl:with-param name = "pX" select = "$pX" />
</xsl:apply-templates>
</xsl:variable>
<xsl:variable name = "vFx_2" >
<xsl:apply-templates select = "$pFun2" >
<xsl:with-param name = "pX" select = "$pX" />
</xsl:apply-templates>
</xsl:variable>
<xsl:value-of select = "$vFx_1 + $vFx_2" />
</xsl:template>
</xsl:stylesheet>
名为mySum
的模板传递两个参数,即一个参数的“函数指针”,以及该单个参数的值。
它调用每个动态传递的函数,并生成结果的总和。
如上所述,这两个函数是:1)double(x)
和2)triple(x)
因此,结果必须为:double(x) + triple(x)
:5*x
事实上,结果是15
,即5 * 3
。这里的转换应用于任何XML文档 - 例如<t/>
- 实际上没有使用它。
建议您修改这两个功能,并在每次产生正确结果时查看。
<强> II。 XSLT 2.0实施:
正如你所看到的,这里的调用实际上传递了两个函数:
f:applyAndSum(f:funTwice(), f:funFiveTimes(), 3)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/" exclude-result-prefixes="f">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:function name="f:apply">
<xsl:param name="pFunc" as="element()"/>
<xsl:param name="arg1"/>
<xsl:apply-templates select="$pFunc" mode="f:FXSL">
<xsl:with-param name="arg1" select="$arg1"/>
</xsl:apply-templates>
</xsl:function>
<xsl:function name="f:apply">
<xsl:param name="pFunc" as="element()"/>
<xsl:param name="arg1"/>
<xsl:param name="arg2"/>
<xsl:apply-templates select="$pFunc" mode="f:FXSL">
<xsl:with-param name="arg1" select="$arg1"/>
<xsl:with-param name="arg2" select="$arg2"/>
</xsl:apply-templates>
</xsl:function>
<xsl:template match="/">
<xsl:sequence select=
"f:applyAndSum(f:funTwice(), f:funFiveTimes(), 3)"/>
</xsl:template>
<xsl:function name="f:applyAndSum">
<xsl:param name="arg1" as="element()"/>
<xsl:param name="arg2" as="element()"/>
<xsl:param name="arg3"/>
<xsl:sequence select=
"f:apply($arg1,$arg3) + f:apply($arg2,$arg3)"/>
</xsl:function>
<xsl:function name="f:funTwice" as="element()">
<f:funTwice/>
</xsl:function>
<xsl:function name="f:funFiveTimes" as="element()">
<f:funFiveTimes/>
</xsl:function>
<xsl:template match="f:funTwice" mode="f:FXSL">
<xsl:param name="arg1"/>
<xsl:sequence select ="f:funTwice($arg1)"/>
</xsl:template>
<xsl:template match="f:funFiveTimes" mode="f:FXSL">
<xsl:param name="arg1"/>
<xsl:sequence select ="f:funFiveTimes($arg1)"/>
</xsl:template>
<xsl:function name="f:funTwice">
<xsl:param name="arg1"/>
<xsl:sequence select="2*$arg1"/>
</xsl:function>
<xsl:function name="f:funFiveTimes">
<xsl:param name="arg1"/>
<xsl:sequence select="5*$arg1"/>
</xsl:function>
</xsl:stylesheet>
这里有两个链接可以更系统地介绍FXSL:
original FXSL page - 这只是XSLT 1.0,
A paper about FXSL 2 - FXSL for XSLT 2.0