XSLT按位逻辑(XSLT Bitwise Logic)

2019-06-25 12:52发布

我有利用的整数来存储多个值的现有的数据集; 遗留前端做一个简单的逐位检查(例如,在C#:iValues&16 == 16),以查看是否一个特定的值被设定。 是否有可能做位运算的XSL,以及更明确地,通过屏蔽做到位水平的比较? 内置的“和”总是会导致“真”或“假”,但也许它通过使用数学运算符的可能吗?

我目前使用.NET 2.0,它使用XSLT 1.0。

Answer 1:

我还没有看到在XSLT / XPath的这样的事。 但我发现有人手动执行这种操作 。 也许你可以用同样的方法,如果你真的需要。



Answer 2:

XSLT是图灵完备的 ,例如参见这里或这里 ,因此它可以做到的。 不过,我已经使用XSLT只有一次或两次,可以给无解。

UPDATE

我刚刚看了一遍教程和使用以下事实,找到了解决办法。 bitset(x, n)返回真,如果n的第比特x被设置,否则返回假。

bitset(x, n) := floor(x / 2^n) mod 2 == 1

下面的XSLT

<?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>

会变成这个XML

<?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>

与示出了数字的位的表的HTML文档。

Number | Bit 3 | Bit 2 | Bit 1 | Bit 0 
---------------------------------------
   0   |   0   |   0   |   0   |   0 
   1   |   0   |   0   |   0   |   1 
   2   |   0   |   0   |   1   |   0 
   3   |   0   |   0   |   1   |   1 
   4   |   0   |   1   |   0   |   0 
   5   |   0   |   1   |   0   |   1 
   6   |   0   |   1   |   1   |   0 
   7   |   0   |   1   |   1   |   1 
   8   |   1   |   0   |   0   |   0 
   9   |   1   |   0   |   0   |   1 
  10   |   1   |   0   |   1   |   0 
  11   |   1   |   0   |   1   |   1 
  12   |   1   |   1   |   0   |   0 
  13   |   1   |   1   |   0   |   1 
  14   |   1   |   1   |   1   |   0 
  15   |   1   |   1   |   1   |   1 

这既不优雅,也不以任何方式不错,有可能是更简单的解决方案,但它的工作原理。 而且因为它是我用XSLT第一次接触,我是比较满意的。



Answer 3:

XSLT没有定义位运算。 如果你希望他们,你必须推出自己的。

如果您使用XSLT特别是在.NET 2.0上下文-也就是说, 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());


Answer 4:

<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"/>

this will return the binary array of your variable (stored in $var)

by the way I used XPath 2.0 to do this



文章来源: XSLT Bitwise Logic