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の答えは良いものです。

ただし、最終的なフィルタリングは子の名前と値の指定に制限されます。

(a に相当する) 関数を parameter として渡すことができることを知っておくとよいでしょう。この非常に強力な概念はFXSL (XSLT の関数型プログラミング ライブラリ) に実装されています。FXSL は、XSLT 自体で完全に記述されています。

フィルター関数/テンプレートを使用した適切な例を次に示します。フィルタをパラメータとして、フィルタリングを実行するテンプレートに渡します。フィルターは、任意のコード/ロジックにすることができます。この特定のケースでは、数値が偶数かどうかをチェックするテンプレートへの参照をパラメーターとして渡しています。完全な変換では、値が偶数である「num」要素のみが出力されます。

まったく同じ手法を使用して、他のフィルタを非常に簡単に渡すことができます: 偶数、平方、素数などをフィルタリング (非) します。

「フィルター」テンプレートを自分で作成する必要はないことに注意してください。これは一度だけ作成され、FXSL ライブラリによって提供されます。結果として、通常は <xsl:import/> ディレクティブを使用して、「フィルター」テンプレートと、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"/>

  <!-- numList.xml に適用 -->

  <xsl:output indent="yes" omit-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:template name="myIsEven" mode="f:FXSL"
    match="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 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"/>

  <!-- Orders.xml に適用 -->

  <xsl:output indent="yes" omit-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"
    match="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 ライブラリ、具体的には文字列を XPath 式として評価できるdyn:evaluate関数を使用します。

于 2008-11-28T11:27:31.583 に答える