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</価格>
</注文>