4

基本上我有一个小模板,看起来像:

<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 &lt; 15" />
</xsl:call-template>

不幸的是,它似乎在调用模板之前对其进行评估(因此有效地传递了“false”)将它括在引号中只会使其成为字符串文字,因此这也不起作用。有谁知道我想要实现的目标是否可行?如果是这样,你能解释一下吗?干杯

4

3 回答 3

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()) &lt; $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”中进行标记。

于 2008-11-28T11:15:24.040 回答
4

Divo 的回答很好。

但是,它将任何最终过滤限制为指定孩子的姓名和值。

很高兴知道可以将一个(相当于一个)函数作为参数传递。这个非常强大的概念在 FXSL 中实现——XSLT的函数式编程库。FXSL 完全用 XSLT 本身编写。

这是使用过滤器功能/模板的适当示例。我们将过滤器作为参数传递给执行过滤的模板。过滤器可以是任何代码/逻辑。在这种特殊情况下,我们将作为参数传递给检查数字是否为偶数的模板的引用。完整的转换仅输出那些值为偶数的“num”个元素。

我们可以很容易地通过任何其他过滤器,使用完全相同的技术:过滤(非)偶数、平方、素数等。

请注意,不必为自己编写“过滤器”模板——它是一次性编写的,并且由 FXSL 库提供。因此,您通常只使用 <xsl:import/> 指令来导入“过滤器”模板和 FXSL 已经提供的许多其他有用的功能/模板。

下面的变换:

<xsl:stylesheet 版本="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"/>

  <!-- 应用于numList.xml -->

  <xsl:output indent="yes" 省略-xml-declaration="yes"/>

  <myIsEven:myIsEven/>

  <xsl:模板匹配="/">
    <xsl:变量名="vIsEven"
         select="document('')/*/myIsEven:*[1]"/>

    按 IsEven 过滤:
    <xsl:call-template name="_filter">
        <xsl:with-param name="pList" select="/*/*"/>
        <xsl:with-param name="pController" select="$vIsEven"/>
    </xsl:调用模板>

  </xsl:模板>

  <xsl:模板名称="myIsEven" 模式="f:FXSL"
    匹配="myIsEven:*">
    <xsl:param name="arg1"/>

    <xsl:if test="$arg1 mod 2 = 0">1</xsl:if>
  </xsl:模板>
</xsl:样式表>

应用于此源 XML 文档时:

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

产生所需的(过滤的)结果,仅包含具有偶数值的节点:

按 IsEven 过滤:
<num>02</num>
<num>04</num>
<num>06</num>
<num>08</num>
<num>10</num>

有关 XSLT 中函数式编程的更多信息可以在FXSL 页面上找到,并且库本身可以从其sourceforce 项目下载。

回到具体问题:

这种转变:

<xsl:stylesheet 版本="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"/>

  <!-- 应用于 Orders.xml -->

  <xsl:output indent="yes" 省略-xml-declaration="yes"/>

  <myFilter:myFilter/>

  <xsl:模板匹配="/">
    <xsl:变量名="vFilter"
         select="document('')/*/myFilter:*[1]"/>

    按 PRICE < 15 过滤:
    <xsl:call-template name="_filter">
        <xsl:with-param name="pList" select="/*/*"/>
        <xsl:with-param name="pController" select="$vFilter"/>
    </xsl:调用模板>

  </xsl:模板>

  <xsl:template name="myFilter" mode="f:FXSL"
    匹配="myFilter:*">
    <xsl:param name="arg1"/>

    <xsl:if test="$arg1/PRICE < 15">1</xsl:if>
  </xsl:模板>
</xsl:样式表>

应用于此源 XML 文档时:

<订单>
  <订单>
    <价格>10</价格>
  </订单>
  <订单>
    <价格>7</价格>
  </订单>
  <订单>
      <价格>22</价格>
</订单>
  <订单>
      <价格>16</价格>
  </订单>
  <订单>
      <价格>13</价格>
  </订单>
  <订单>
      <价格>19</价格>
  </订单>
</订单>  

产生想要的结果:

按 PRICE < 15 过滤:
<订单>
   <价格>10</价格>
</订单>
<订单>
   <价格>7</价格>
</订单>
<订单>
   <价格>13</价格>
</订单>
于 2008-11-29T03:40:11.170 回答
3

使用 EXSLT 库,特别是dyn:evaluate函数,它可以将字符串计算为 XPath 表达式。

于 2008-11-28T11:27:31.583 回答