2009-07-09 5 views
7

Ho un set di dati esistente che utilizza un numero intero per memorizzare più valori; il front-end precedente eseguiva un semplice controllo bit a bit (ad esempio in C#: iValues ​​& 16 == 16) per verificare se era stato impostato un determinato valore. È possibile eseguire operazioni bit a bit in XSL e, in modo più esplicito, eseguire confronti a livello di bit tramite mascheramento? Il built-in "e" genererà sempre "vero" o "falso", ma forse è possibile tramite gli operatori matematici disponibili?XSLT Bitwise Logic

Attualmente sto utilizzando .NET 2.0, che utilizza XSLT 1.0.

risposta

3

Non ho visto nulla di simile in XSLT/XPath. Ma ho trovato someone implementing this kind of operations manually. Forse potresti usare lo stesso approccio, se proprio ne hai bisogno.

+0

Bella ricerca; dovevo semplicemente cambiare il modello con nome per accettare il numero come parametro e funzionava come un campione per qualsiasi valore arbitrario. – pdwetz

13

XSLT è Turing-complete, vedere ad esempio here o here, quindi è possibile farlo. Ma ho usato XSLT solo una o due volte e non posso dare alcuna soluzione.

UPDATE

Ho appena letto di nuovo un tutorial e ha trovato una soluzione che utilizza il seguente fatto. bitset(x, n) restituisce true, se il n bit di x è impostato, false altrimenti.

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

Di seguito 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> 

si trasformerà questo 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> 

in un documento HTML con una tabella che mostra i bit dei numeri.

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 

Questo è né elegante né bello in alcun modo e ci sono probabilmente soluzione molto più semplice, ma funziona. E dato che è il mio primo contatto con XSLT, sono abbastanza soddisfatto.

+2

In che modo il completamento di Turing rappresenta la risposta se esistono operatori bit a bit? –

+2

Se è completo di Turing, può calcolare ogni funzione, quindi operazioni bit a bit su numeri interi. –

+0

Hmm ...Non capisco Ho familiarità con la nozione di completezza di Turing, ma posso ancora immaginare un linguaggio che è completo e non ha operatori bit-saggi, cioè non ci sono mezzi per dividere i numeri in blocchi più piccoli. –

3

XSLT non definisce operazioni bit a bit. Se li vuoi, devi tirare il tuo.

Se si sta utilizzando XSLT in particolare nel contesto NET 2.0 - vale a dire, XslCompiledTransform classe - allora la soluzione più semplice è quello di utilizzare un blocco di script per introdurre una funzione di C# che lo fa, e poi basta chiamare che:

Oppure è possibile definire più primitive di alto livello in un blocco di script, ad esempio HasFlag, e quindi utilizzarle.

Quando si carica un tale foglio di stile, è necessario abilitare esplicitamente script in esso:

XslCompiledTransform xslt = new XslCompiledTransform(); 
xslt.Load("foo.xsl", 
    new XsltSettings { EnableScript = true }, 
    new XmlUrlResolver()); 
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"/> 

Ciò restituirà la matrice binaria della variabile (memorizzata in $ var)

da il modo in cui ho usato XPath 2.0 per fare questo

+2

Grazie, ma non applicabile a .NET framework (come da domanda originale, che purtroppo è ancora il caso di .NET 4.0). La tua soluzione funziona solo se stai utilizzando una libreria di terze parti con supporto per XPath 2.0. – pdwetz