Xslt如何设置条件奇数/偶数行的样式

时间:2010-07-15 10:41:35

标签: xml xslt html-table conditional

我有一个使用xslt转换编写的html表,看起来像这样

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

我需要一种方法来应用不同的类oddRow / evenRow到tr elems。

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

我尝试在每个&lt; tr&gt;之后使用这样的模板。 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>

但这不起作用。 任何想法?

3 个答案:

答案 0 :(得分:17)

您可以在just css

中完成此操作
tr:nth-child(odd) {
    /*...*/
}
tr:nth-child(odd) {
    /*...*/
}

如果你不能,你可以做类似

的事情
<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>

请注意,我在SO文本框中写了这个并且没有测试过它。

答案 1 :(得分:3)

此转化

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

应用于此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>

产生想要的结果

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

请注意

  1. 我们正在使用最细粒度的遍历和处理XML文档 - 逐个节点。在身份转换之后,这是第二个最重要的XSLT设计模式。

  2. 其他小技巧并不重要

答案 2 :(得分:0)

向表中添加样式的conditionalRowStyle模板看起来与构建表的样式表位于相同的样式表中。如果是这种情况,则它将无法按预期工作,因为conditionalRowStyle模板中选择的节点将来自源文档(包含someNode)而不是目标文档(生成的表元素所在的位置)是)。

您可以通过先将someNode模板的表格输出收集到变量来“破解”这个,然后您可以先运行conditionalRowStyle模板,然后再输出变量值作为结果样式表。但是使用两个样式表要简单得多,在管道中一个接一个地运行。第一个样式表将someNode数据转换为表格,第二个样式表将conditionalRowStyle格式应用于表格。