2010-07-15 27 views
8

Tengo una tabla html escrito usando transformación XSLT que tiene este aspectoXslt cómo Estilo condicionales pares/impares filas

<table> 
    <xsl:for-each select="someNode"> 
     <xsl:if test="testThis"> 
      <tr> 
       <!-- <xsl:call-template name="conditionalRowStyle"/> --> 
       <td>something</td> 
      </tr> 
     </xsl:if> 
     <tr> 
      <!-- <xsl:call-template name="conditionalRowStyle"/> --> 
      <td>this is always displayed</td> 
     </tr> 
     <xsl:if test="testThis2"> 
      <tr> 
       <!-- <xsl:call-template name="conditionalRowStyle"/> --> 
       <td>something 2</td> 
      </tr> 
     </xsl:if> 
     .... 
    </xsl:for-each> 
    <tr> 
     <!-- <xsl:call-template name="conditionalRowStyle"/> --> 
     <td>this is always displayed</td> 
    </tr> 
</table> 

Necesito una manera de aplicar diferentes clases oddRow/evenRow a TR elems.

<tr class="evenRow"> or <tr class="oddRow"> 

He intentado utilizar una plantilla como esta después de cada <tr> elem

<xsl:template name="conditionalRowStyle"> 
    <xsl:attribute name="class"> 
     <xsl:choose> 
      <xsl:when test="(count(../preceding-sibling::tr) mod 2) = 0">oddrow</xsl:when> 
      <xsl:otherwise>evenrow</xsl:otherwise> 
     </xsl:choose> 
    </xsl:attribute> 
</xsl:template> 

pero esto no está funcionando. alguna idea?

+0

Excelente pregunta (+1). Vea mi respuesta para una solución XSLT 1.0 de un solo paso :) –

Respuesta

17

Usted probablemente podría salirse con hacer esto en just css

tr:nth-child(odd) { 
    /*...*/ 
} 
tr:nth-child(odd) { 
    /*...*/ 
} 

Si no puede, usted podría hacer algo como

<xsl:attribute name="class"> 
    <xsl:choose> 
     <xsl:when test="(position() mod 2) != 1"> 
      <xsl:text>evenRow</xsl:text> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:text>oddRow</xsl:text> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:attribute> 

Tenga en cuenta que he escrito esto en el cuadro de texto SO y no tienen probado.

+0

Esto no funcionará, ya que los nodos seleccionados son los datos de origen utilizados para construir la tabla, no la tabla en sí. – mdma

+0

Gracias por su resp. Tus soluciones no funcionarán No puedo usar las propiedades de CSS como en otras tablas. Necesito imprimir mediante programación más de 2 filas del mismo color. test = "(posición() mod 2)! = 1 se rompe cuando uso if declaraciones para mostrar filas condicionales – mickthompson

0

Parece que la plantilla conditionalRowStyle para agregar estilos a la tabla está en la misma hoja de estilo que la que está formando la tabla. Si ese es el caso, no funcionará como se esperaba, ya que los nodos seleccionados en la plantilla conditionalRowStyle serán del documento de origen (que contiene someNode) y no el documento de destino (donde están los elementos de tabla generados)

Usted puede "piratear" esto reuniendo primero el resultado de la tabla de las plantillas someNode en una variable, que luego puede ejecutar primero la plantilla conditionalRowStyle antes de generar finalmente el valor de la variable como resultado de la hoja de estilo. Pero es mucho más simple usar dos hojas de estilo, que se ejecutan una tras otra en una tubería. La primera hoja de estilo convierte los datos de someNode en una tabla, y la segunda aplica el formato conditionalRowStyle a la tabla.

3

Esta transformación:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ext="http://exslt.org/common" 
exclude-result-prefixes="ext"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:variable name="vrtfTrs"> 
    <tr> 
    <td>something</td> 
    </tr> 
    <tr> 
    <td>This is always displayed</td> 
    </tr> 
    <tr> 
    <td>something 2</td> 
    </tr> 
</xsl:variable> 

<xsl:variable name="vTrs" select="ext:node-set($vrtfTrs)/*"/> 

<xsl:template match="/nums"> 
    <html> 
    <table> 
     <xsl:apply-templates select="num[1]"/> 
    </table> 
    </html> 
</xsl:template> 

<xsl:template match="num"> 
    <xsl:param name="pCount" select="0"/> 

    <xsl:variable name="vTest1" select=". mod 4 = 1"/> 
    <xsl:variable name="vTest2" select=". mod 4 = 2"/> 

    <xsl:apply-templates select="$vTrs[1][$vTest1]"> 
    <xsl:with-param name="pCount" select="$pCount +1"/> 
    <xsl:with-param name="pnodevalue" select="."/> 
    </xsl:apply-templates> 

    <xsl:apply-templates select="$vTrs[2]"> 
    <xsl:with-param name="pCount" select="$pCount+$vTest1 +1"/> 
    <xsl:with-param name="pnodevalue" select="."/> 
    </xsl:apply-templates> 

    <xsl:apply-templates select="$vTrs[3][$vTest2]"> 
    <xsl:with-param name="pCount" select="$pCount+$vTest1 +2"/> 
    <xsl:with-param name="pnodevalue" select="."/> 
    </xsl:apply-templates> 

    <xsl:apply-templates select="following-sibling::*[1]"> 
    <xsl:with-param name="pCount" 
      select="$pCount+1+$vTest1+$vTest2"/> 
    <xsl:with-param name="pnodevalue" select="."/> 
    </xsl:apply-templates> 

    <xsl:if test="not(following-sibling::*)"> 
     <xsl:apply-templates select="$vTrs[2]"> 
     <xsl:with-param name="pCount" select="$pCount+1+$vTest1+$vTest2"/> 
     <xsl:with-param name="pnodevalue" select="."/> 
     </xsl:apply-templates> 
    </xsl:if> 
</xsl:template> 

<xsl:template match="tr"> 
    <xsl:param name="pCount"/> 
    <xsl:param name="pnodevalue"/> 

    <tr class="{concat(substring('even', 1 div ($pCount mod 2 = 0)), 
        substring('odd', 1 div ($pCount mod 2 = 1)) 
        )}"> 
    <xsl:comment>&lt;num><xsl:value-of select="$pnodevalue"/>&lt;/num></xsl:comment> 
    <xsl:copy-of select="node()"/> 
    </tr> 
</xsl:template> 
</xsl:stylesheet> 

cuando se aplica en este documento XML:

<nums> 
    <num>01</num> 
    <num>02</num> 
    <num>03</num> 
    <num>04</num> 
    <num>05</num> 
    <num>06</num> 
    <num>07</num> 
    <num>08</num> 
    <num>09</num> 
    <num>10</num> 
</nums> 

produce el resultado deseado:

<html> 
    <table> 
     <tr class="odd"> 
     <!--<num>01</num>--> 
     <td>something</td> 
     </tr> 
     <tr class="even"> 
     <!--<num>01</num>--> 
     <td>This is always displayed</td> 
     </tr> 
     <tr class="odd"> 
     <!--<num>02</num>--> 
     <td>This is always displayed</td> 
     </tr> 
     <tr class="even"> 
     <!--<num>02</num>--> 
     <td>something 2</td> 
     </tr> 
     <tr class="odd"> 
     <!--<num>03</num>--> 
     <td>This is always displayed</td> 
     </tr> 
     <tr class="even"> 
     <!--<num>04</num>--> 
     <td>This is always displayed</td> 
     </tr> 
     <tr class="odd"> 
     <!--<num>05</num>--> 
     <td>something</td> 
     </tr> 
     <tr class="even"> 
     <!--<num>05</num>--> 
     <td>This is always displayed</td> 
     </tr> 
     <tr class="odd"> 
     <!--<num>06</num>--> 
     <td>This is always displayed</td> 
     </tr> 
     <tr class="even"> 
     <!--<num>06</num>--> 
     <td>something 2</td> 
     </tr> 
     <tr class="odd"> 
     <!--<num>07</num>--> 
     <td>This is always displayed</td> 
     </tr> 
     <tr class="even"> 
     <!--<num>08</num>--> 
     <td>This is always displayed</td> 
     </tr> 
     <tr class="odd"> 
     <!--<num>09</num>--> 
     <td>something</td> 
     </tr> 
     <tr class="even"> 
     <!--<num>09</num>--> 
     <td>This is always displayed</td> 
     </tr> 
     <tr class="odd"> 
     <!--<num>10</num>--> 
     <td>This is always displayed</td> 
     </tr> 
     <tr class="even"> 
     <!--<num>10</num>--> 
     <td>something 2</td> 
     </tr> 
     <tr class="even"> 
     <!--<num>10</num>--> 
     <td>This is always displayed</td> 
     </tr> 
    </table> 
</html> 

hacer la nota:

  1. Estamos utilizando el recorrido más de grano fino y el procesamiento de un documento XML - nodo por nodo. Después de la transformación de identidad, este es el segundo patrón de diseño XSLT más importante.

  2. El resto de los pequeños trucos no son tan importantes.

+0

+1 Excelente! Rompiendo la recursión e yendo secuencialmente con el siguiente eje ... –

+0

@Alejandro: Sí, tenemos que recordar que a veces '' es demasiado grosero. –

+0

elegir el impar, incluso el inicio de sesión es asombroso. – kalyan

Cuestiones relacionadas