当值在xslt中发生变化时,如何交替行颜色

时间:2018-01-20 20:56:30

标签: xslt

如果我制作一个xslt报告,其中包含如下行: 如果列中的值发生更改,则行颜色或字体颜色应更改。怎么做 ?我试过分组是不成功的。

123  - white row colour
123  - white row colour
876  - grey row colour
848  - white row colour
543  - grey row colour
543  - grey row colour
543  - grey row colour

2 个答案:

答案 0 :(得分:0)

如果您不想/不能使用CSS来解决这个问题或者仅限于XSLT 1.0(无<xsl:for-each-group group-adjacent...>),那么这个问题可以迭代解决。要正确地交替行颜色,必须知道为它之前的行拾取颜色的每一行。

XSLT中的迭代是通过递归来完成的:调用第一个项目的模板,让它找出颜色,然后让模板调用自己,直到它用完项目,每一步传递当前颜色。

假设这种输入:

<document>
  <data>123</data>
  <data>123</data>
  <data>876</data>
  <data>848</data>
  <data>543</data>
  <data>543</data>
  <data>543</data>
</document>

以下程序使用此过程来交替颜色:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:template match="document">
    <xsl:copy>
      <xsl:for-each select="data[1]">
        <xsl:call-template name="rows" />  
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>

  <xsl:template name="rows">
    <xsl:param name="previous_color" />

    <xsl:variable name="color">
      <xsl:choose>
        <xsl:when test=". = preceding-sibling::*[1]"><xsl:value-of select="$previous_color" /></xsl:when>
        <xsl:when test="$previous_color = 'white'">grey</xsl:when>
        <xsl:otherwise>white</xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <data color="{$color}"><xsl:value-of select="." /></data>

    <xsl:for-each select="following-sibling::*[1]">
      <xsl:call-template name="rows">
        <xsl:with-param name="previous_color" select="$color" />
      </xsl:call-template>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

并制作

<document>
  <data color="white">123</data>
  <data color="white">123</data>
  <data color="grey">876</data>
  <data color="white">848</data>
  <data color="grey">543</data>
  <data color="grey">543</data>
  <data color="grey">543</data>
</document>

请注意,<xsl:for-each>每次仅用于单个节点。所有这一切都改变了当前节点&#34; (.)从<data>到下一个mark,当然它会阻止最后一步的无限递归。

答案 1 :(得分:0)

如果目标格式是HTML,那么一种方法是将相邻的行分组为tbody元素,并将交替的背景颜色样式委托给CSS

        tbody:nth-child(odd) {
          background-color: white;
        }
        tbody:nth-child(even) {
          background-color: grey;
        }

使用for-each-group group-adjacent轻松地在XSLT 2或3中对第一列的相邻值进行分组:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:output method="html" indent="yes" html-version="5"/>

  <xsl:template match="/">
    <html>
      <head>
        <title>.NET XSLT Fiddle Example</title>
        <style>
            tbody:nth-child(odd) {
              background-color: white;
            }
            tbody:nth-child(even) {
              background-color: grey;
            }
        </style>
      </head>
      <body>
          <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="data">
      <table>
          <xsl:for-each-group select="row" group-adjacent="col[1]">
              <tbody>
                  <xsl:apply-templates select="current-group()"/>
              </tbody>
          </xsl:for-each-group>
      </table>
  </xsl:template>

  <xsl:template match="row">
      <tr>
          <xsl:apply-templates/>
      </tr>
  </xsl:template>

  <xsl:template match="col">
      <td>
          <xsl:apply-templates/>
      </td>
  </xsl:template>

</xsl:stylesheet>

http://xsltfiddle.liberty-development.net/bFukv8g