XSL хранит набор узлов в переменной - PullRequest
8 голосов
/ 14 марта 2011

(XSLT 1.0.) Дана переменная с именем Rows, которая содержит следующее (пример):

Input

<AllResults>
    <Result>
      <subject>can be filtered by filter 1</subject>
      <type>can be filtered by filter 2</type>
      <date>can be filtered by filter 3</date>
    </Result>
    <Result> ...
    </Result>
</AllResults>

У меня есть 3 переменные фильтра. Для каждого фильтра я хотел бы применить фильтр к входу, показанному выше, если переменная фильтра не пуста. Я хотел бы сохранить отфильтрованный результат, элементы, которые соответствуют фильтрам, в новую переменную. Я попробовал следующее, но я получил сообщение об ошибке (filterResult), являющееся «деревом результатов вместо набора узлов». Переменная Rows - это набор узлов, как я определил с помощью отладчика.

Часть XSL

<xsl:variable name="filterResult">
    <xsl:choose>
        <xsl:when test="$filter1 != '' and $filter2 != '' and $filter3 != ''">
            <xsl:copy-of select="$Rows[date=$filter1 and type=$filter2 and subject=$filter3]" />
        </xsl:when>
        <xsl:when test="$filter1 != '' and $filter2 != ''">
            <xsl:copy-of select="$Rows[date=$filter1 and type=$filter2]" />
        </xsl:when>
        <xsl:when test="$filter1 != '' and $filter3 != ''">
            <xsl:copy-of select="$Rows[date=$filter1 and subject=$filter3]" />
        </xsl:when>
        <xsl:when test="$filter3 != '' and $filter2 != ''">
            <xsl:copy-of select="$Rows[type=$filter2 and subject=$filter3]" />
        </xsl:when>
        <xsl:when test="$filter1 != ''">
            <xsl:copy-of select="$Rows[date=$filter1]" />
        </xsl:when>
        <xsl:when test="$filter3 != ''">
            <xsl:copy-of select="$Rows[subject=$filter3]" />
        </xsl:when>
        <xsl:when test="$filter2 != ''">
            <xsl:copy-of select="$Rows[type=$filter2]" />
        </xsl:when>
        <xsl:otherwise> 
            <xsl:copy-of select="$Rows" />
        </xsl:otherwise>
    </xsl:choose>
</xsl:variable>

Я понимаю, что copy-of создает дерево результатов, а не набор узлов, но я не уверен, КАК производить набор узлов, учитывая мои требования к 3 фильтрам, которые я описал выше.

Дополнительная информация

Я знаю, что мог бы сделать что-то вроде <xsl:variable name="me" select="/set/node"/>, которое могло бы создать переменную, содержащую набор узлов, но я не понимаю, как это мне помогает, поскольку у меня много возможных условий (учитывая три фильтра).

Ответы [ 2 ]

11 голосов
/ 14 марта 2011

В XSLT 1.0 единственным способом создания переменной, содержащей набор узлов из исходного документа, является оценка выражения XPath в атрибуте select:

<xsl:variable name="name" select="xpath_expression"/>

Вы не можете использоватьcopy-of, apply-templates или call-template;все они производят фрагмент результирующего дерева.

Каждый процессор XSLT, о котором я знаю, реализует функцию расширения, которая преобразует фрагменты результирующего дерева в наборы узлов, поэтому если вам не нужно, чтобы преобразование было полностью кроссплатформенным,может сделать что-то вроде этого (в этом примере используется процессор Microsoft XSLT):

<xsl:variable name="filterResultNodeSet" select="msxsl:node-set($filterResult)"/>

Но вам не нужно делать даже этого: как отметил Алехандро, вы можете получить результат, который вы ищетепросто написав одно выражение XPath.Существуют приложения, в которых выбор узла настолько сложен, что вам приходится использовать функцию node-set(), но ваша не входит в их число.

7 голосов
/ 14 марта 2011

Похоже, $Rows переменная является экземпляром типа Result Tree Fragment.

Вы не можете выполнять какие-либо операции (например, те, которые предоставляются выражением фильтра []) с RTF, кроме строковых операций: с http://www.w3.org/TR/xslt#section-Result-Tree-Fragments

Операция разрешена для результата фрагмент дерева, только если эта операция будет разрешено на строку ( операция над строкой может включать сначала преобразовать строку в число или логическое значение). В частности, это не разрешается использовать /, //, и [] операторы в дереве результатов фрагменты.

Кроме того, весь показанный код может быть упрощен, если $Rows является экземпляром типа данных набора узлов, подобным этому:

<xsl:variable name="filterResult" 
              select="$Rows[(date=$filter1 or $filter1='')
                               and 
                            (type=$filter2 or $filter2='')
                               and 
                            (subject=$filter3 or $filter3='')]"/>

Существуют XSLT-процессоры (в основном каждый), которые предоставляют реализации функции расширения node-set() для преобразования RTF в набор узлов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...