Problem: Należy odwrócić łańcuch znaków. Np. łańcuch "abcdef" odwrócić do postaci "fedcba".
Rozwiązanie:
XSLT 1.0:
<xsl:template name="reverse"> <xsl:param name="input"/> <xsl:variable name="len" select="string-length($input)"/> <xsl:choose> <!-- Odwrócenie łańcuchów znaków o długości poniżej dwóch znaków jest trywialne --> <xsl:when test="$len &lt; 2"> <xsl:value-of select="$input"/> </xsl:when> <!-- Odwrócenie łańcuchów znaków o długości równej dwa jest także trywialne --> <xsl:when test="$len = 2"> <xsl:value-of select="substring($input,2,1)"/> <xsl:value-of select="substring($input,1,1)"/> </xsl:when> <xsl:otherwise> <!-- Zamień rekurencyjne zastosowanie tego szablonu na pierwszą część i drugą część danych wejściowych --> <xsl:variable name="mid" select="floor($len div 2)"/> <xsl:call-template name="reverse"> <xsl:with-param name="input" select="substring($input,$mid+1,$mid+1)"/> </xsl:call-template> <xsl:call-template name="reverse"> <xsl:with-param name="input" select="substring($input,1,$mid)"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template>
XSLT 2.0:
<xsl:function name="ckbk:reverse"> <xsl:param name="input" as="xs:string"/> <xsl:sequence select="codepoints-to-string(reverse(string-to-codepoints($input)))"/> </xsl:function>
Algorytm zaprezentowany w rozwiązaniu jest bardzo wydajny i dobrze radzi sobie z odwracaniem nawet bardzo długich łańcuchów znaków. Podstawą zaprezentowanego algorytmu jest zamiana pierwszej połowy łańcucha znaków z drugą połową i stosowanie tego algorytmu rekurencyjnie, dopóki nie otrzyma się łańcuchów o długości dwóch znaków lub mniejszych. Poniższy przykład pokazuje, jak działa algorytm:
- reverse("abcdef") (dane wejściowe)
- reverse("def") + reverse("abc")
- reverse("ef") + "d" + reverse("bc") + "a"
- "f" + "e" + "d" + "c" + "b" + "a"
- "fedcba" (wynik)
Źródło: XSLT. Receptury, Helion 2007







