我有一个使用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>
但这不起作用。 任何想法?
答案 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><num><xsl:value-of select="$pnodevalue"/></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>
请注意:
我们正在使用最细粒度的遍历和处理XML文档 - 逐个节点。在身份转换之后,这是第二个最重要的XSLT设计模式。
其他小技巧并不重要。
答案 2 :(得分:0)
向表中添加样式的conditionalRowStyle
模板看起来与构建表的样式表位于相同的样式表中。如果是这种情况,则它将无法按预期工作,因为conditionalRowStyle
模板中选择的节点将来自源文档(包含someNode
)而不是目标文档(生成的表元素所在的位置)是)。
您可以通过先将someNode
模板的表格输出收集到变量来“破解”这个,然后您可以先运行conditionalRowStyle
模板,然后再输出变量值作为结果样式表。但是使用两个样式表要简单得多,在管道中一个接一个地运行。第一个样式表将someNode
数据转换为表格,第二个样式表将conditionalRowStyle
格式应用于表格。