使用XSLT的表的替代行颜色

时间:2011-11-16 18:42:52

标签: xslt

我有一个XSLT,我想要交替输出表的行颜色。我知道您可以使用此示例中的代码:

<table>
<tr>
    <td>Name</td>
    <td>ID</td>
</tr>
<xsl:for-each select="//Book">
    <xsl:variable name="altColor">
        <xsl:choose>
            <xsl:when test="position() mod 2 = 0">#FFFFFF</xsl:when>
            <xsl:otherwise>#D3DFEE</xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <tr bgcolor="{$altColor}">
        <td><xsl:value-of select="current()/@name"/></td>
        <td><xsl:value-of select="current()/@ID"/></td>
    </tr>
</xsl:for-each>
</table>

但工作正常,我有几个实例,我需要在for-each中包含一些if语句,例如。

<table>
<tr>
    <td>Name</td>
    <td>ID</td>
</tr>
<xsl:for-each select="//Book">
    <xsl:variable name="altColor">
        <xsl:choose>
            <xsl:when test="position() mod 2 = 0">#FFFFFF</xsl:when>
            <xsl:otherwise>#D3DFEE</xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <xsl:if test="current()/@ID &gt; 10000 and current/@ID &lt; 6000">
        <tr bgcolor="{$altColor}">
            <td><xsl:value-of select="current()/@name"/></td>
            <td><xsl:value-of select="current()/@ID"/></td>
        </tr>
    </xsl:if>
</xsl:for-each>
</table>

然后它不起作用,因为它可能会跳过for-each中某个位置的项目,最后会以随机交替的行颜色结束,或者它可能从不正确的位置开始,其中行以不正确的颜色开始交替。

我尝试过添加xsl:sort,但这并没有真正解决问题。有没有办法避免这种障碍?

3 个答案:

答案 0 :(得分:1)

尝试使用以下代码:

tr[position() mod 2 =0]

&#13;
&#13;
<xsl:template match="n1:tr[position() mod 2 =0]">
 
   <tr bgcolor="#aaaaaa">
 
     <xsl:apply-templates/>

    </tr> 
  </xsl:template>
  


  <xsl:template match="n1:tr[position() mod 2 =1]">

    <tr bgcolor="#aaaaff">

      <xsl:apply-templates/>

    </tr>

  </xsl:template>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

一个简单的解决方案是记住最后使用的颜色,而不是使用相反的颜色 相反,你的选择基于position(),你也应该在测试中移动选择行

这里是伪代码

currentColor = color1
for each 
if ( id > 10000 and id < 6000 ) {
  if ( currentColor == color1 )
      currentColor= color2
  else 
      currentColor = color1
  showDataInColor(currentColor)
}

答案 2 :(得分:0)

最简单的解决方案(将您的样本样式表作为您实际需求的代表)是首先仅循环遍历所需的节点。像这样:

<xsl:template match="/">
    <table>
        <tr>
            <td>Name</td>
            <td>ID</td>
        </tr>
        <xsl:for-each select="//Book[@ID &lt; 10000 and @ID &gt; 6000]">
            <xsl:variable name="altColor">
                <xsl:choose>
                    <xsl:when test="position() mod 2 = 0">#FFFFFF</xsl:when>
                    <xsl:otherwise>#D3DFEE</xsl:otherwise>
                </xsl:choose>
            </xsl:variable>
        <tr bgcolor="{$altColor}">
            <td><xsl:value-of select="@name" /></td>
            <td><xsl:value-of select="@ID" /></td>
        </tr>
        </xsl:for-each>
    </table>
</xsl:template>

换句话说,不是有条件地在for-each的主体中包含节点,而只需选择您需要的那些节点。通过这样做,position()将相对于您正在迭代的集合,并且它将按预期工作。

例如,这个(简化的)输入:

<r>
    <Book ID="6200"/>
    <Book ID="7100"/>
    <Book/>
    <Book/>
    <Book ID="8000"/>
    <Book/>
    <Book ID="9001"/>
    <Book ID="9002"/>
</r>

产生正确的交替:

<table>
    <tr>
        <td>Name</td>
        <td>ID</td>
    </tr>
    <tr bgcolor="#D3DFEE">
        <td />
        <td>6200</td>
    </tr>
    <tr bgcolor="#FFFFFF">
        <td />
        <td>7100</td>
    </tr>
    <tr bgcolor="#D3DFEE">
        <td />
        <td>8000</td>
    </tr>
    <tr bgcolor="#FFFFFF">
        <td />
        <td>9001</td>
    </tr>
    <tr bgcolor="#D3DFEE">
        <td />
        <td>9002</td>
    </tr>
</table>