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
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
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
aram name="arg1" as="xs:integer"/>
<xsl
aram 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
aram name="arg1" as="xs:integer"/>
<xsl
aram 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
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
aram name="arg1"/>
<xsl
aram 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
aram name="arg1"/>
<xsl
aram 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