XSL: Как лучше хранить node в переменной, а затем мы ее в будущих выражениях xpath?

Мне нужно иметь возможность хранить набор node в переменной, а затем после этого выполнять дополнительную обработку/сортировку. Все примеры, которые я видел, связаны с использованием XSL2 или расширений, ни один из которых не является действительно вариантом.

У меня есть список отелей в моем XML-документе, который можно сортировать/фильтровать, а затем выгружать по 5 за раз. Я нахожу, хотя я повторяю много логики, так как в настоящее время я не нашел хороший способ хранения node -sets в переменной 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>

Есть ли у кого-нибудь пример того, как лучше всего это делать?

Ответы

Ответ 1

Попробуйте этот пример:

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

Ответ 2

Нет проблемы с хранением node -set в переменной в XSLT 1.0, и никаких расширений не требуется. Если вы просто используете выражение XPath в атрибуте select xsl:variable, вы в конечном итоге сделаете именно это.

Проблема заключается только в том, что вы хотите сохранить узлы, которые вы сами создали в переменной, и даже тогда, только если вы захотите запросить их позже. Проблема здесь в том, что выведенные узлы не имеют типа "node -set" - вместо этого они называются "фрагментом дерева результатов". Вы можете сохранить это значение переменной, и вы можете использовать эту переменную для вставки фрагмента в вывод (или другую переменную) позже, но вы не можете использовать XPath для запроса по нему. Если вам нужна функция EXSLT node-set() (которая преобразует фрагмент результирующего дерева в node -set) или XSLT 2.0 (в котором нет фрагментов дерева результатов, только последовательности узлов, независимо от того, откуда они происходят).

Для вашего примера, как указано, это не кажется проблемой. Ответ Rubens дает точный синтаксис.

Ответ 3

Еще одно замечание: если вы хотите использовать эту переменную как часть оператора XPath, вам нужно выбрать в переменной <xsl:copy-of select="."/> вместо <xsl:value-of select="."/>

значение принимает только текст node, и вы не сможете использовать функцию 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>