基本上我有一个小模板,如下所示:
<xsl:template name="templt">
<xsl:param name="filter" />
<xsl:variable name="numOrders" select="count(ORDERS/ORDER[$filter])" />
</xsl:template>
我试图用
来调用它<xsl:call-template name="templt">
<xsl:with-param name="filter" select="PRICE < 15" />
</xsl:call-template>
不幸的是,它似乎在调用模板之前对其进行评估(因此传入有效的“false”)将其括在引号中只会使它成为字符串文字,因此也不起作用。有人知道我想要实现的目标是否可行?如果是这样,你能否对它有所了解?干杯
答案 0 :(得分:6)
以下内容如何:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template name="templt">
<xsl:param name="filterNodeName" />
<xsl:param name="filterValue" />
<xsl:variable name="orders" select="ORDERS/ORDER/child::*[name() = $filterNodeName and number(text()) < $filterValue]" />
<xsl:for-each select="$orders">
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="/">
<xsl:call-template name="templt">
<xsl:with-param name="filterNodeName" select="'PRICE'" />
<xsl:with-param name="filterValue" select="15" />
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>
如果您仍然只想使用单个参数,则可以首先在模板'templt'中进行标记。
答案 1 :(得分:4)
Divo的答案很好。
但是,它会将任何最终过滤限制为指定子项的名称和值。
很高兴知道一个人可以传递一个(多于一个)函数作为参数。这个非常强大的概念在FXSL - XSLT的功能编程库中实现。 FXSL完全用XSLT编写。
以下是使用the filter function/template的相应示例。我们将过滤器作为参数传递给执行过滤的模板。过滤器可以是任何代码/逻辑。在这种特殊情况下,我们将参数作为参数传递给模板,该模板检查数字是否为偶数。完整转换仅输出那些“num”元素,其值为偶数。
我们可以使用完全相同的技术轻松传递任何其他过滤器:过滤(联合)偶数,正方形,素数等......
请注意,一个人不必自己编写“过滤器”模板 - 它一次性写入并由FXSL库提供。因此,您通常只使用&lt; xsl:import /&gt;指令导入“过滤器”模板和FXSL已经提供的许多其他有用的功能/模板。
以下转型:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:f="http://fxsl.sf.net/" xmlns:myIsEven="myIsEven" > <xsl:import href="filter.xsl"/> <!-- To be applied on numList.xml --> <xsl:output indent="yes" omit-xml-declaration="yes"/> <myIsEven:myIsEven/> <xsl:template match="/"> <xsl:variable name="vIsEven" select="document('')/*/myIsEven:*[1]"/> Filtering by IsEven: <xsl:call-template name="_filter"> <xsl:with-param name="pList" select="/*/*"/> <xsl:with-param name="pController" select="$vIsEven"/> </xsl:call-template> </xsl:template> <xsl:template name="myIsEven" mode="f:FXSL" match="myIsEven:*"> <xsl:param name="arg1"/> <xsl:if test="$arg1 mod 2 = 0">1</xsl:if> </xsl:template> </xsl:stylesheet>
应用于此源XML文档时:
<nums> <num>01</num> <num>02</num> <num>03</num> <num>04</num> <num>05</num> <num>06</num> <num>07</num> <num>08</num> <num>09</num> <num>10</num> </nums>
生成所需(已过滤)的结果,仅包含具有偶数值的节点:
Filtering by IsEven: <num>02</num> <num>04</num> <num>06</num> <num>08</num> <num>10</num>
可以在page of FXSL上找到有关XSLT中的函数编程的更多信息,并且可以从其sourceforce project下载库本身。
回到具体问题:
这种转变:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:f="http://fxsl.sf.net/" xmlns:myFilter="myFilter" > <xsl:import href="filter.xsl"/> <!-- To be applied on Orders.xml --> <xsl:output indent="yes" omit-xml-declaration="yes"/> <myFilter:myFilter/> <xsl:template match="/"> <xsl:variable name="vFilter" select="document('')/*/myFilter:*[1]"/> Filtering by PRICE < 15: <xsl:call-template name="_filter"> <xsl:with-param name="pList" select="/*/*"/> <xsl:with-param name="pController" select="$vFilter"/> </xsl:call-template> </xsl:template> <xsl:template name="myFilter" mode="f:FXSL" match="myFilter:*"> <xsl:param name="arg1"/> <xsl:if test="$arg1/PRICE < 15">1</xsl:if> </xsl:template> </xsl:stylesheet>
应用于此源XML文档时:
<ORDERS> <ORDER> <PRICE>10</PRICE> </ORDER> <ORDER> <PRICE>7</PRICE> </ORDER> <ORDER> <PRICE>22</PRICE> </ORDER> <ORDER> <PRICE>16</PRICE> </ORDER> <ORDER> <PRICE>13</PRICE> </ORDER> <ORDER> <PRICE>19</PRICE> </ORDER> </ORDERS>
产生想要的结果:
Filtering by PRICE < 15: <ORDER> <PRICE>10</PRICE> </ORDER> <ORDER> <PRICE>7</PRICE> </ORDER> <ORDER> <PRICE>13</PRICE> </ORDER>
答案 2 :(得分:3)
使用EXSLT库,特别是dyn:evaluate函数,它可以将字符串计算为XPath表达式。