Bit testing in XSLT

The information below is an extract from a panel presentation at XML DevCon London February 2001 responding to a question submitted prior to the conference.

Question submitted by Kimberly Hahn:

A trick that programmers often use to determine settings is to
store those settings as an integer in the database (2 for blue
background, 4 for open full screen on initial load, etc. the
field would store 6 if the user wanted both turned on).  Then
use bit-wise operations to determine if the particular setting
the programmer was interested in has been turned on or off
((40 and 8) > 1 being true so 8 is on, (40 and 4)>1 being
false so 4 is not on).  It does not appear that XSLT supports
this type of operation.  Is there a way of achieving this
without resorting to script in the transformation, in other
words using the Microsoft xslt extension that allows you to
use script?

Bit testing can be done without scripting use modulo arithmetic in binary. Consider the testing of bit 7 in the number 480:

bits.gif

To strip out the bits above the bit desired, the remainder is calculated from the next highest binary number of the bit (in this case 256).

To strip out the bits below the bit desired, the remainder is calculated from the binary number of the bit (in this case 128), and then subtracted from the previous remainder.

The resulting number is non-zero if the bit is turned on, and zero if the bit is turned off.

The following stylesheet illustrates this:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

<xsl:output method="text"/>

<xsl:param name="num"/>

<!--summary of powers of two-->
<xsl:variable name="bit15" select="32768"/>
<xsl:variable name="bit14" select="16384"/>
<xsl:variable name="bit13" select="8192"/>
<xsl:variable name="bit12" select="4096"/>
<xsl:variable name="bit11" select="2048"/>
<xsl:variable name="bit10" select="1024"/>
<xsl:variable name="bit9"  select="512"/>
<xsl:variable name="bit8"  select="256"/>
<xsl:variable name="bit7"  select="128"/>
<xsl:variable name="bit6"  select="64"/>
<xsl:variable name="bit5"  select="32"/>
<xsl:variable name="bit4"  select="16"/>
<xsl:variable name="bit3"  select="8"/>
<xsl:variable name="bit2"  select="4"/>
<xsl:variable name="bit1"  select="2"/>
<xsl:variable name="bit0"  select="1"/>

<xsl:template name="bit">
  <xsl:param name="bit" select="1"/>
  <xsl:choose>
    <xsl:when test="( $num mod ( $bit * 2 ) ) -
                    ( $num mod ( $bit     ) )">1</xsl:when>
    <xsl:otherwise>0</xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="/">
  <xsl:text>Bit 7 on? </xsl:text>
  <xsl:choose>
    <xsl:when test="( $num mod 256 ) - ( $num mod 128 )">yes</xsl:when>
    <xsl:otherwise>no</xsl:otherwise>
  </xsl:choose>

  <xsl:text>
Bit 0 on? </xsl:text>
  <xsl:choose>
    <xsl:when test="( $num mod 2 )">yes</xsl:when>
    <xsl:otherwise>no</xsl:otherwise>
  </xsl:choose>

  <xsl:text>
Binary:</xsl:text>
  <xsl:call-template name="bit"><xsl:with-param name="bit" select="$bit15"/></xsl:call-template>
  <xsl:call-template name="bit"><xsl:with-param name="bit" select="$bit14"/></xsl:call-template>
  <xsl:call-template name="bit"><xsl:with-param name="bit" select="$bit13"/></xsl:call-template>
  <xsl:call-template name="bit"><xsl:with-param name="bit" select="$bit12"/></xsl:call-template>
  <xsl:call-template name="bit"><xsl:with-param name="bit" select="$bit11"/></xsl:call-template>
  <xsl:call-template name="bit"><xsl:with-param name="bit" select="$bit10"/></xsl:call-template>
  <xsl:call-template name="bit"><xsl:with-param name="bit" select="$bit9"/></xsl:call-template>
  <xsl:call-template name="bit"><xsl:with-param name="bit" select="$bit8"/></xsl:call-template>
  <xsl:call-template name="bit"><xsl:with-param name="bit" select="$bit7"/></xsl:call-template>
  <xsl:call-template name="bit"><xsl:with-param name="bit" select="$bit6"/></xsl:call-template>
  <xsl:call-template name="bit"><xsl:with-param name="bit" select="$bit5"/></xsl:call-template>
  <xsl:call-template name="bit"><xsl:with-param name="bit" select="$bit4"/></xsl:call-template>
  <xsl:call-template name="bit"><xsl:with-param name="bit" select="$bit3"/></xsl:call-template>
  <xsl:call-template name="bit"><xsl:with-param name="bit" select="$bit2"/></xsl:call-template>
  <xsl:call-template name="bit"><xsl:with-param name="bit" select="$bit1"/></xsl:call-template>
  <xsl:call-template name="bit"><xsl:with-param name="bit" select="$bit0"/></xsl:call-template>

</xsl:template>

</xsl:stylesheet>

The following illustrates the invocation of the stylesheet:

S:\conferences\2001\Camelot-London>xt test.xsl test.xsl num=480
Bit 7 on? yes
Bit 0 on? no
Binary:0000000111100000
S:\conferences\2001\Camelot-London>xt test.xsl test.xsl num=270
Bit 7 on? no
Bit 0 on? no
Binary:0000000100001110
S:\conferences\2001\Camelot-London>xt test.xsl test.xsl num=127
Bit 7 on? no
Bit 0 on? yes
Binary:0000000001111111
S:\conferences\2001\Camelot-London>xt test.xsl test.xsl num=128
Bit 7 on? yes
Bit 0 on? no
Binary:0000000010000000
S:\conferences\2001\Camelot-London>xt test.xsl test.xsl num=65535
Bit 7 on? yes
Bit 0 on? yes
Binary:1111111111111111
S:\conferences\2001\Camelot-London>
Crane logo
CRANE
SOFTWRIGHTS
LTD.
 GIT REPOSITORIES 
 RESOURCES RSS XML 

Please consider to


towards our
free resources.

+1 (613) 489-0999 (Voice)

info@CraneSoftwrights.com


Link traversal: This web site relies heavily on client-side redirection. If certain links do not work for you, please ensure you have this behaviour enabled in your browser.

Site navigation:

Small print: All use of this web site and all business conducted with Crane Softwrights Ltd. is subject to the legal disclaimers detailed at http://www.CraneSoftwrights.com/legal ... please contact us if you have any questions. All trademarks, servicemarks, registered trademarks, and registered servicemarks are the property of their respective owners.

Link legend: links that are marked with this dotted underline will open up a new browser window, otherwise the same browser window is used for the link target. 

Last changed: $Date: 2006/12/27 19:59:11 $(UTC) (Privacy policy)