Вот более эффективное решение, чем принятое в настоящее время, которое не использует функцию reverse()
:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:my="my:my">
<xsl:output method="text"/>
<xsl:function name="my:subSequences" as="xs:string*">
<xsl:param name="pString" as="xs:string"/>
<xsl:param name="pstartLength" as="xs:integer"/>
<xsl:sequence select=
"for $totalLength in string-length($pString),
$length in 1 to $totalLength -$pstartLength +1,
$revLength in $totalLength -$length +1
return
substring($pString, 1, $revLength)"/>
</xsl:function>
<xsl:template match="/">
<xsl:value-of select="my:subSequences('12345', 2)" separator=","/>
</xsl:template>
</xsl:stylesheet>
Когда выполняется это преобразование, получается нужный, правильный результат :
12345,1234,123,12
Объяснение :
Спецификация XPath 2.0 W3C определяет, что если первый аргумент оператора to
больше второго аргумента, то результирующая последовательность будет пустой последовательностью.
Все еще можно обойти это ограничение и построить убывающую целочисленную последовательность, например:
for $k in 0 to $big - $small
return
$big - $k
Использование такого выражения более эффективно, особенно для больших последовательностей, чем сначала создание возрастающей последовательности, а затем ее обращение с помощью функции reverse()
.