Требуется рассматривать числа как битовые маски, хотя в языке XSLT нет понятия целого числа а, значит, нет и поразрядных операций.
При работе с XML не пытайтесь во чтобы бы то ни стало закодировать информацию в виде набора битов. Применяйте это решение лишь тогда, когда не можете контролировать способ представления данных.
Этот способ проверки битов (шаблон bitTest), основанный на арифметике по модулю, обсуждался на конференции XML DevCon, состоявшейся в 2001 году в Лондоне. Мы реализовали поразрядные логические операции рекурсивно с помощью операций сравнения и вычитания, но можно было бы воспользоваться операциями деления и взятия остатка, как показано ниже:
<xsl:templatename="bitAnd"><xsl:paramname="num1"/><xsl:paramname="num2"/><xsl:paramname="result"select="0"/><xsl:paramname="pow2"select="$bit0"/><xsl:choose><xsl:whentest="$num1 < 1 or $num2 < 1"><xsl:value-ofselect="$result"/></xsl:when><xsl:whentest="$num1 mod 2 and $num2 mod 2"><xsl:call-templatename="bitAnd"><xsl:with-paramname="num1"select="floor($num1 div 2)"/><xsl:with-paramname="num2"select="floor($num2 div 2)"/><xsl:with-paramname="result"select="$result + $pow2"/><xsl:with-paramname="pow2"select="$pow2 * 2"/>Проверкабитов
</xsl:call-template></xsl:when><xsl:otherwise><xsl:call-templatename="bitAnd"><xsl:with-paramname="num1"select="floor($num1 div 2)"/><xsl:with-paramname="num2"select="floor($num2 div 2)"/><xsl:with-paramname="result"select="$result"/><xsl:with-paramname="pow2"select="$pow2 * 2"/></xsl:call-template></xsl:otherwise></xsl:choose></xsl:template>
<xsl:templatename="bitOr"><xsl:paramname="num1"/><xsl:paramname="num2"/><xsl:paramname="result"select="0"/><xsl:paramname="pow2"select="$bit0"/><xsl:choose><xsl:whentest="$num1 < 1 and $num2 < 1"><xsl:value-ofselect="$result"/></xsl:when><xsl:whentest="boolean($num1 mod 2) or boolean($num2 mod 2)"><xsl:call-templatename="bitOr"><xsl:with-paramname="num1"select="floor($num1 div 2)"/><xsl:with-paramname="num2"select="floor($num2 div 2)"/><xsl:with-paramname="result"select="$result + $pow2"/><xsl:with-paramname="pow2"select="$pow2 * 2"/></xsl:call-template></xsl:when><xsl:otherwise><xsl:call-templatename="bitOr"><xsl:with-paramname="num1"select="floor($num1 div 2)"/><xsl:with-paramname="num2"select="floor($num2 div 2)"/><xsl:with-paramname="result"select="$result"/><xsl:with-paramname="pow2"select="$pow2 * 2"/></xsl:call-template></xsl:otherwise></xsl:choose></xsl:template>
<xsl:templatename="bitXor"><xsl:paramname="num1"/><xsl:paramname="num2"/><xsl:paramname="result"select="0"/><xsl:paramname="pow2"select="$bit0"/><xsl:choose><xsl:whentest="$num1 < 1 and $num2 < 1"><xsl:value-ofselect="$result"/></xsl:when><xsl:whentest="$num1 mod 2 + $num2 mod 2 = 1"><xsl:call-templatename="bitXor"><xsl:with-paramname="num1"select="floor($num1 div 2)"/><xsl:with-paramname="num2"select="floor($num2 div 2)"/><xsl:with-paramname="result"select="$result + $pow2"/><xsl:with-paramname="pow2"select="$pow2 * 2"/></xsl:call-template></xsl:when><xsl:otherwise><xsl:call-templatename="bitXor"><xsl:with-paramname="num1"select="floor($num1 div 2)"/><xsl:with-paramname="num2"select="floor($num2 div 2)"/><xsl:with-paramname="result"select="$result"/><xsl:with-paramname="pow2"select="$pow2 * 2"/></xsl:call-template></xsl:otherwise></xsl:choose></xsl:template>
Найти решение для версии 2.0 оставляю читателю в качестве упражнения. Как и в других рецептах, следует преобразовать шаблоны в функции и заменить идиоматические выражения для работы с булевскими величинами – ($num1 >= $test) * ($num1 - $test) + not($num1 >= $test) * $num1 – выражениями if-then-else.