Xslt, как стилизовать условные нечетные / четные строки - PullRequest
8 голосов
/ 15 июля 2010

У меня есть html таблица, написанная с использованием преобразования xslt, которая выглядит следующим образом

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

Я пытался использовать такой шаблон после каждого

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 ]

17 голосов
/ 15 июля 2010

Вы могли бы, вероятно, сделать это в просто 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 и не проверял его.

3 голосов
/ 16 июля 2010

Это преобразование :

<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. Остальные маленькие хитрости не так важны .

0 голосов
/ 15 июля 2010

Похоже, что шаблон conditionalRowStyle для добавления стилей в таблицу находится в той же таблице стилей, что и таблица, из которой строится таблица.Если это так, то он не будет работать должным образом, так как узлы, выбранные в шаблоне conditionalRowStyle, будут из исходного документа (содержащего someNode), а не из целевого документа (где созданы элементы таблицы.)

Вы можете «взломать» это, сначала собрав выходные данные таблицы шаблонов someNode в переменную, после чего вы можете сначала запустить шаблон conditionalRowStyle, прежде чем, наконец, вывести значение переменной в результатетаблицы стилей.Но гораздо проще использовать две таблицы стилей, которые вы запускаете одну за другой в конвейере.Первая таблица стилей преобразует данные someNode в таблицу, а вторая применяет форматирование conditionalRowStyle к таблице.

...