I need to convert a hexadecimal value to an integer value, how can I do that using XSLT?
For example, if the input is hexadecimal FF
, my output should be 255.
Converting hexadecimal to decimal in pure XSLT 1.0:
<xsl:template name="hex2num">
<xsl:param name="hex"/>
<xsl:param name="num" select="0"/>
<xsl:param name="MSB" select="translate(substring($hex, 1, 1), 'abcdef', 'ABCDEF')"/>
<xsl:param name="value" select="string-length(substring-before('0123456789ABCDEF', $MSB))"/>
<xsl:param name="result" select="16 * $num + $value"/>
<xsl:choose>
<xsl:when test="string-length($hex) > 1">
<xsl:call-template name="hex2num">
<xsl:with-param name="hex" select="substring($hex, 2)"/>
<xsl:with-param name="num" select="$result"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$result"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Edit: Sorry, my bad I just noted the OP asked for hex to decimal and not the other way around.
hexToDecimal template for XSLT-1.0:
<xsl:template name="hexToDecimal">
<xsl:param name="hex"/>
<xsl:variable name="dec"
select="string-length(substring-before('0123456789ABCDEF', substring($hex,1,1)))"/>
<xsl:choose>
<xsl:when test="$hex = ''">0</xsl:when>
<xsl:otherwise>
<xsl:variable name="rest">
<xsl:call-template name="hexToDecimal">
<xsl:with-param name="hex">
<xsl:value-of select="substring($hex,2)"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$dec * math:power(16, string-length($hex) - 1) + $rest"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
This needs math:power
from exslt http://exslt.org/math/
hexToDecimal function for XSLT-2.0:
<xsl:function name="f:hexToDec">
<xsl:param name="hex"/>
<xsl:variable name="dec"
select="string-length(substring-before('0123456789ABCDEF', substring($hex,1,1)))"/>
<xsl:choose>
<xsl:when test="matches($hex, '([0-9]*|[A-F]*)')">
<xsl:value-of
select="if ($hex = '') then 0
else $dec * f:power(16, string-length($hex) - 1) + f:hexToDec(substring($hex,2))"/>
</xsl:when>
<xsl:otherwise>
<xsl:message>Provided value is not hexadecimal...</xsl:message>
<xsl:value-of select="$hex"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
<xsl:function name="f:power">
<xsl:param name="base"/>
<xsl:param name="exp"/>
<xsl:sequence
select="if ($exp lt 0) then f:power(1.0 div $base, -$exp)
else if ($exp eq 0)
then 1e0
else $base * f:power($base, $exp - 1)"
/>
</xsl:function>
Leaving this here, also it was not asked for, it might still be useful.
There is no directly implemented function in xslt, so you would have to write it yourself.
Here's a template for XSLT 1.0:
<xsl:template name="decimalToHex">
<xsl:param name="dec"/>
<xsl:if test="$dec > 0">
<xsl:call-template name="decimalToHex">
<xsl:with-param name="dec" select="floor($dec div 16)"/>
</xsl:call-template>
<xsl:value-of select="substring('0123456789ABCDEF', (($dec mod 16) + 1), 1)"/>
</xsl:if>
</xsl:template>
You call it like this:
<xsl:call-template name="decimalToHex">
<xsl:with-param name="dec">4095</xsl:with-param>
</xsl:call-template>
And a function for XSLT 2.0:
<xsl:function name="f:decimalToHex">
<xsl:param name="dec"/>
<xsl:if test="$dec > 0">
<xsl:value-of
select="f:decimalToHex(floor($dec div 16)),substring('0123456789ABCDEF', (($dec mod 16) + 1), 1)"
separator=""
/>
</xsl:if>
</xsl:function>
Which you can call like this:
<xsl:value-of select="f:decimalToHex(4095)"/>
Be aware that you have to declare the namespace for the function in you stylesheet.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With