Проблема, возникшая при использовании xsl: для каждого цикла запроса вместо select=»expr» в xsl:variable

#xml #xslt #saxon

#xml #xslt #саксонский

Вопрос:

Я получаю разные значения для переменной $ var, когда использую 2 разных метода для выбора элементов:-

 <xsl:variable name="var" select="$doc//ns:abc | $doc//ns:xyz"/>

<xsl:message select="count($var)"/>
  

дает соответствующее количество

Однако

 <xsl:variable name="var" >
    <xsl:for-each select="$doc//ns:abc | $doc//ns:xyz">
        <xsl:copy-of select="."/>
    </xsl:for-each>
</xsl:variable>

<xsl:message select="count($var)"/>
  

дает 1

Как получить соответствующий счетчик, используя также для каждого цикла. Поскольку я хочу хранить элементы в отсортированном порядке, что можно сделать только с помощью xsl:sort/ в xsl:for-each/ .

Ответ №1:

В случае

 <xsl:variable name="var" >
    <xsl:for-each select="$doc//ns:abc | $doc//ns:xyz">
        <xsl:copy-of select="."/>
    </xsl:for-each>
</xsl:variable>
  

значением переменной является отдельный узел фрагмента документа, содержащий копию выбранных вами элементов.

Вам нужно будет использовать as атрибут в xsl:variable и xsl:sequence

 <xsl:variable name="var" as="node()*">
    <xsl:for-each select="$doc//ns:abc | $doc//ns:xyz">
        <xsl:sequence select="."/>
    </xsl:for-each>
</xsl:variable>
  

или просто

 <xsl:variable name="var" as="node()*">
    <xsl:sequence select="$doc//ns:abc | $doc//ns:xyz"/>
</xsl:variable>
  

чтобы выбрать узлы из входного документа в виде последовательности узлов.

Обратите внимание, что XPath 3 sort также имеет функции, поэтому, возможно, даже если вам нужно сортировать входные узлы, вам не нужны элементы XSLT, такие как xsl:for-each/xsl:sort or xsl:perform-sort/xsl:sort , но вы можете просто использовать sort функцию в вашем select выражении XPath.

Комментарии:

1. Или использовать count($var/*) .

2. @michael.hor257k, ну, да, если мы ограничимся строгим ответом на вопрос «Как получить соответствующий счетчик, используя для каждого цикла». Но для всей проблемы я предпочитаю предлагать использовать as атрибут и убедиться xsl:sequence , что он используется, чтобы избежать накладных расходов на копирование узлов.

3. Я не пытался вам противоречить (на самом деле, я был в процессе написания ответа, очень похожего на ваш, когда вы опубликовали), просто чтобы упомянуть еще одну возможность, которая также добавляет еще одну иллюстрацию основной проблемы здесь.