Xslt how to style conditional odd/even rows

前端 未结 3 1504
梦谈多话
梦谈多话 2021-02-08 22:39

I\'ve an html table written using xslt transformation that looks like this


        

        
                      
相关标签:
3条回答
  • 2021-02-08 23:08

    It looks like the conditionalRowStyle template to add styles to the table is in the same stylesheet as the one building the table. If that's the case, then it will not work as expected, since the nodes selected in the conditionalRowStyle template will be from the source document (containing someNode) and not the target document (where the generated table elements are.)

    You can "hack" this by collecting the table output of the someNode templates to a variable first, which you can then run the conditionalRowStyle template on first before finally outputting the variable value as the result of the stylesheet. But it's much simpler to use two stylesheets, that you run one after the other in a pipeline. The first stylesheet converts the someNode data to a table, and the second applies conditionalRowStyle formatting to the table.

    0 讨论(0)
  • 2021-02-08 23:23

    This transformation:

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

    when applied on this XML document:

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

    produces the wanted result:

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

    Do note:

    1. We are using the most fine-grained traversal and processing of an XML document -- node by node. After the identity transformation this is the second most important XSLT design pattern.

    2. The rest of the small tricks are not that important.

    0 讨论(0)
  • 2021-02-08 23:26

    You could probably get away with doing this in just css

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

    If you cannot, you could do something like

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

    Note that i wrote this in the SO textbox and haven't tested it.

    0 讨论(0)
提交回复
热议问题