web-dev-qa-db-ja.com

XSL:ノードを変数に格納して、将来のxpath式で使用する方法

ノードセットを変数に格納し、後でそのノードに対してさらにフィルタリング/ソートを実行できるようにする必要があります。これについて私が見たすべての例には、XSL2または拡張機能の使用が含まれますが、どちらも実際にはオプションではありません。

XMLドキュメントに、並べ替え/フィルター処理が可能なホテルのリストがあり、一度に5つずつページングできます。私は現在、多くのロジックを繰り返していますが、ノードセットをxsl変数に格納し、それらにxpathを使用してさらにフィルタリング/ソートするための良い方法を見つけられないので、見つけています。

これは私が求めているものです(頭のてっぺんに書かれたコードが100%とは限らないので)。

<xsl:variable name="hotels" select="/results/hotels[active='true']" />
<xsl:variable name="3_star_or_less" select="/results/hotels[number(rating) <= 3]" />
<xsl:for-each select="3_star_or_less">
  <xsl:sort select="rating" />
</xsl:for-each>

このようなことをするのに最適な方法の例を誰かが持っていますか?

17
Pete Duncanson

この例を試してください:

<xsl:variable name="hotels" select="/results/hotels[active='true']" />
<xsl:variable name="three_star_or_less"
              select="$hotels[number(rating) &lt;= 3]" />
<xsl:for-each select="$three_star_or_less">
    <xsl:sort select="rating" />
    <xsl:value-of select="rating" />
</xsl:for-each>
22
Rubens Farias

XSLT 1.0では、変数にノードセットを格納することに問題はなく、拡張も必要ありません。 _xsl:variable_のselect属性でXPath式を使用するだけの場合は、最終的にそれを行うことになります。

問題は、自分自身が生成したであるノードを変数に格納する場合に限られます。それでも、後でそれらを照会する場合に限られます。ここでの問題は、出力するノードのタイプが「ノードセット」ではないことです。代わりに、それらは「結果ツリーフラグメント」と呼ばれるものです。これを変数に格納し、後でその変数を使用してフラグメントを出力(または別の変数)に挿入できますが、XPathを使用してそれをクエリすることはできません。これは、EXSLT node-set()関数(結果ツリーフラグメントをノードセットに変換する)、またはXSLT 2.0(結果ツリーフラグメントはなく、ノードのシーケンスのみ、どこにあるかに関係なく)が必要な場合です。から来る)。

与えられた例では、これは問題ではないようです。ルーベンスの答えは正確な構文を与えます。

6
Pavel Minaev

変数をXPathステートメントの一部として使用できるようにする場合は、<xsl:copy-of select="."/>ではなく<xsl:value-of select="."/>を使用して変数を選択する必要があることに注意してください。

value-ofはノードのテキストのみを取得し、node-set関数を使用して意味のあるものを返すことはできません。

<xsl:variable name="myStringVar">
   <xsl:value-of select="."/>
</xsl:variable>

<!-- This won't work: -->
<Output>
   <xsl:value-of select="node-set($myStringVar)/SubNode" />
</Output>


<xsl:variable name="myNodeSetVar">
   <xsl:copy-of select="."/>
</xsl:variable>

<!-- This will work: -->
<Output>
   <xsl:value-of select="node-set($myNodeSetVar)/SubNode" />
</Output>
5
K0D4