Xslt, как разработать условные нечетные/ровные строки

У меня есть таблица 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">

Я пытался использовать шаблон как это после каждого <TR> элемент

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

но это не работает. какая-либо идея?

8
задан Brian Tompsett - 汤莱恩 5 June 2017 в 20:10
поделиться

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

3
ответ дан 5 December 2019 в 08:22
поделиться

Вам, вероятно, удастся сделать это в только 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 и убежище Не тестировал.

17
ответ дан 5 December 2019 в 08:22
поделиться

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

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

0
ответ дан 5 December 2019 в 08:22
поделиться