XSLT binary to decimal

R

RolfK

Dear ALL,

I have to convert a string of "10101010111"to a decimal number.

What is the standard solution in XSLT2.0 ?

Thanks a lot

RolfK
 
M

Martin Honnen

RolfK said:
I have to convert a string of "10101010111"to a decimal number.

What is the standard solution in XSLT2.0 ?

http://www.dpawson.co.uk/xsl/rev2/functions2.html#d16818e694 has an
example of hex to decimal conversion. I applied that to binary to
decimal conversion as follows:

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/2008/mf"
exclude-result-prefixes="xsd mf"
version="2.0">

<xsl:function name="mf:bin2dec" as="xsd:integer">
<xsl:param name="input" as="xsd:string"/>
<xsl:sequence
select="if (string-length($input) eq 1)
then xsd:integer($input)
else 2 * mf:bin2dec(substring($input, 1,
string-length($input) - 1)) + xsd:integer(substring($input,
string-length($input)))"/>
</xsl:function>

<xsl:template match="/">
<xsl:value-of select="mf:bin2dec('10101010111')"/>
</xsl:template>

</xsl:stylesheet>

but I have not tested in detail.
 
D

Dimitre Novatchev

RolfK said:
Dear ALL,

I have to convert a string of "10101010111"to a decimal number.

What is the standard solution in XSLT2.0 ?

Thanks a lot

RolfK

This is trivial using FXSL.

Below are three solutions, one using, respectively, the functions
f:zipWith(), f:foldl() and f:str-foldl():

testFunc-zipWithBits.xsl:
=================
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:f="http://fxsl.sf.net/"
exclude-result-prefixes="f xs" <xsl:import href="../f/func-zipWithDVC.xsl"/>
<xsl:import href="../f/func-Operators.xsl"/>

<xsl:eek:utput method="text"/>

<xsl:variable name="vBits" as="xs:string" select="'10101010111'"/>

<xsl:variable name="vZeroBits" as="xs:string"
select="'00000000000000000000000000000000000000'"/>

<xsl:variable name="vbinPowers" as="xs:integer+"
select="1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768"/>

<xsl:template match="/">

<xsl:sequence select=
"sum(f:zipWith(f:mult(),
$vbinPowers,
reverse(f:zipWith(f:subtr(),
string-to-codepoints($vBits),
string-to-codepoints($vZeroBits)
)
)
)
)"
/>
</xsl:template>
</xsl:stylesheet>


testFun-foldlBits.xsl:
==============
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:f="http://fxsl.sf.net/"
exclude-result-prefixes="f xs" <xsl:import href="../f/func-foldl.xsl"/>
<xsl:import href="../f/func-zipWith.xsl"/>
<xsl:import href="../f/func-Operators.xsl"/>

<xsl:eek:utput method="text"/>

<xsl:variable name="vBits" as="xs:string" select="'10101010111'"/>

<xsl:variable name="vZeroBits" as="xs:string"
select="'00000000000000000000000000000000000000'"/>

<xsl:template match="/">

<xsl:variable name="vintBits" as="xs:integer*"
select="f:zipWith(f:subtr(),
string-to-codepoints($vBits),
string-to-codepoints($vZeroBits)
)"
/>

<xsl:sequence select=
"f:foldl(f:binAccum(), 0, $vintBits)"
/>
</xsl:template>

<xsl:function name="f:binAccum" as="xs:integer">
<xsl:param name="arg1" as="xs:integer"/>
<xsl:param name="arg2" as="xs:integer"/>

<xsl:sequence select="2*$arg1 + $arg2"/>
</xsl:function>

<xsl:function name="f:binAccum" as="element()">
<f:binAccum/>
</xsl:function>

<xsl:template match="f:binAccum" mode="f:FXSL">
<xsl:param name="arg1" as="xs:integer"/>
<xsl:param name="arg2" as="xs:integer"/>

<xsl:sequence select="f:binAccum($arg1,$arg2)"/>
</xsl:template>
</xsl:stylesheet>

testFunc-str-foldlBits.xsl:
==================
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="f xs"
<xsl:import href="../f/func-str-foldl.xsl"/>

<xsl:eek:utput method="text"/>

<xsl:variable name="vstrBits" as="xs:string"
select="'10101010111'"/>

<xsl:template match="/">
<xsl:sequence select="f:str-foldl(f:binAccum(), 0, $vstrBits)"/>
</xsl:template>

<xsl:function name="f:binAccum" as="xs:integer">
<xsl:param name="arg1"/>
<xsl:param name="arg2"/>

<xsl:sequence select="2*xs:integer($arg1) + xs:integer($arg2)"/>
</xsl:function>

<xsl:function name="f:binAccum" as="element()">
<f:binAccum/>
</xsl:function>

<xsl:template match="f:binAccum" mode="f:FXSL">
<xsl:param name="arg1"/>
<xsl:param name="arg2"/>

<xsl:sequence select="f:binAccum($arg1,$arg2)"/>
</xsl:template>
</xsl:stylesheet>


All three transformations above produce the correct result:
1367


Cheers,
Dimitre Novatchev
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,173
Messages
2,570,939
Members
47,484
Latest member
JackRichard

Latest Threads

Top