Bit testing in XSLTThe 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: 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
SOFTWRIGHTS LTD. |
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.
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.