我有一个现有的数据集,它利用一个整数来存储多个值;传统前端进行了简单的按位检查(例如在C#:iValues& 16 == 16)以查看是否设置了特定值。是否可以在XSL中进行按位运算,更明确地说,是否可以通过屏蔽进行位级比较?内置的“和”将始终导致“真”或“假”,但也许可以通过数学运算符获得?
我目前正在使用.NET 2.0,它使用XSLT 1.0。
答案 0 :(得分:14)
XSLT为Turing-complete,例如参见here或here,因此可以完成。但是我只使用了一到两次XSLT并且无法解决问题。
<强>更新强>
我刚刚再次阅读了一个教程,并使用以下事实找到了解决方案。 bitset(x, n)
如果设置了n
的{{1}},则返回true,否则返回false。
x
以下XSLT
bitset(x, n) := floor(x / 2^n) mod 2 == 1
将转换此XML
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<table border="1" style="text-align:center;">
<tr bgcolor="#9acd32">
<th>Number</th>
<th>Bit 3</th>
<th>Bit 2</th>
<th>Bit 1</th>
<th>Bit 0</th>
</tr>
<xsl:for-each select="numbers/number">
<tr>
<td>
<xsl:value-of select="."/>
</td>
<td>
<xsl:choose>
<xsl:when test="floor(. div 8) mod 2 = 1">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</td>
<td>
<xsl:choose>
<xsl:when test="floor(. div 4) mod 2 = 1">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</td>
<td>
<xsl:choose>
<xsl:when test="floor(. div 2) mod 2 = 1">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</td>
<td>
<xsl:choose>
<xsl:when test="floor(. div 1) mod 2 = 1">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
到一个HTML文档中,其中的表格显示了数字的位数。
<?xml version="1.0" encoding="ISO-8859-1"?>
<numbers>
<number>0</number>
<number>1</number>
<number>2</number>
<number>3</number>
<number>4</number>
<number>5</number>
<number>6</number>
<number>7</number>
<number>8</number>
<number>9</number>
<number>10</number>
<number>11</number>
<number>12</number>
<number>13</number>
<number>14</number>
<number>15</number>
</numbers>
这既不优雅也不好,并且可能有更简单的解决方案,但它有效。鉴于这是我第一次接触XSLT,我非常满意。
答案 1 :(得分:3)
我在XSLT / XPath中没有看到这样的东西。但我发现someone implementing this kind of operations manually。如果你真的需要,也许你可以使用相同的方法。
答案 2 :(得分:3)
XSLT没有定义按位运算。如果你想要它们,你必须自己动手。
如果您在.NET 2.0上下文中特别使用XSLT - 即XslCompiledTransform
类 - 那么最简单的解决方案是使用脚本块来引入执行它的C#函数,然后只调用它:
<xsl:stylesheet xmlns:bitwise="urn:bitwise">
<msxsl:script language="CSharp" implements-prefix="bitwise">
<![CDATA[
public int and(int x, int y) { return x & y; }
public int or(int x, int y) { return x | y; }
...
]]>
</msxsl:script>
...
<xsl:value-of select="bitwise:and(@foo, @bar)" />
<xsl:value-of select="bitwise:or(@foo, @bar)" />
...
</xsl:stylesheet>
或者您可以在脚本块中定义更高级的基元,例如HasFlag
,然后使用它们。
加载这样的样式表时,您需要在其中明确启用脚本:
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load("foo.xsl",
new XsltSettings { EnableScript = true },
new XmlUrlResolver());
答案 3 :(得分:1)
<xsl:value-of select="for $n in (128, 64, 32, 16, 8, 4, 2, 1) return if ((floor($var div $n) mod 2) = 1) then 1 else 0"/>
这将返回变量的二进制数组(存储在$ var中)
顺便说一句,我用XPath 2.0来做这个