2011-02-15

something like strcmp(3) in XSLT 1.0

I had a need to compare alphanumeric string. Unfortunately XSLT 1.0 does
not have string comparison, nor even function to extract character code from
character. So following example works only for string with letters and
numbers. All other characters are treated equally, just after "z" and "_"
of the dictionary order.

<xsl:template name="strcmpAN">
<xsl:param name="a"/>
<xsl:param name="b"/>
<xsl:variable name="ia">
<xsl:call-template name="charCodeAN">
<xsl:with-param name="s" select="$a"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="ib">
<xsl:call-template name="charCodeAN">
<xsl:with-param name="s" select="$b"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$a = $b">
<xsl:value-of select="number(0)"/>
</xsl:when>
<xsl:when test="string-length($b) = 0">
<xsl:value-of select="number(1)"/>
</xsl:when>
<xsl:when test="string-length($a) = 0">
<xsl:value-of select="number(-1)"/>
</xsl:when>
<xsl:when test="$ia &gt; $ib">
<xsl:value-of select="number(1)"/>
</xsl:when>
<xsl:when test="$ia &lt; $ib">
<xsl:value-of select="number(-1)"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="strcmpAN">
<xsl:with-param name="a" select="substring($a, 2)"/>
<xsl:with-param name="b" select="substring($b, 2)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

<xsl:template name="charCodeAN">
<xsl:param name="s"/>
<xsl:param name="i" select="1"/>
<xsl:variable name="CHARTABLE"
select="'
0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz_'"/>
<xsl:choose>
<xsl:when test="$i &gt; string-length($CHARTABLE)">
<xsl:value-of select="string-length($CHARTABLE) + 1"/>
</xsl:when>
<xsl:when test="substring($CHARTABLE, $i, 1) = substring($s, 1, 1)">
<xsl:value-of select="$i"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="charCodeAN">
<xsl:with-param name="s" select="$s"/>
<xsl:with-param name="i" select="$i + 1"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

No comments :

Post a Comment