8

整数を使用して複数の値を格納する既存のデータ セットがあります。従来のフロント エンドは、特定の値が設定されているかどうかを確認するために、簡単なビット単位のチェックを行いました (例: C#: iValues & 16 == 16)。XSL でビット単位の操作を行うことは可能ですか? より明示的に、マスキングを介してビット レベルの比較を行うことはできますか? 組み込みの「and」は常に「true」または「false」になりますが、利用可能な数学演算子を介して可能でしょうか?

現在、XSLT 1.0 を使用する .NET 2.0 を使用しています。

4

4 に答える 4

14

XSLTはチューリング完全です。たとえば、ここまたはここを参照してください。したがって、これを実行できます。しかし、私はXSLTを1〜2回しか使用しておらず、解決策を提供できません。

アップデート

チュートリアルをもう一度読んで、次の事実を使用して解決策を見つけました。の-番目のビットが設定されbitset(x, n)ている場合はtrueを返し、そうでない場合はfalseを返します。nx

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との最初の接触であることを考えると、私は非常に満足しています。

于 2009-07-09T20:05:55.687 に答える
3

XSLT はビット演算を定義しません。それらが必要な場合は、自分でロールする必要があります。

特に .NET 2.0 コンテキスト (つまり、XslCompiledTransformクラス) で XSLT を使用している場合、最も簡単な解決策は、スクリプト ブロックを使用してそれを実行する 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());
于 2009-07-09T21:42:11.483 に答える
3

XSLT / XPath でこのようなものは見たことがありません。しかし、この種の操作を手動で実装している人を見つけました。本当に必要な場合は、同じアプローチを使用できます。

于 2009-07-09T21:17:36.150 に答える
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に格納されている)が返されます

ちなみに私はこれを行うためにXPath2.0を使用しました

于 2011-02-24T12:30:34.363 に答える