我正在把这头发拉出来,可能是因为我是XSL的新手。我一直在使用JavaScript,但除了一件事,XSL似乎更好地完成了工作。
我想使用table而不是div,因为我需要单元格在给定行上具有相同的高度。我可以使用display:table
对div进行此操作,但它确实让我遇到了同样的问题 - 将行放到正确的位置。
Abel提交的工作模板是:
<table>
<tbody>
<xsl:apply-templates select="club[position() mod 2 = 1]" mode="row" />
</tbody>
</table>
<xsl:template match="club" mode="row">
<tr>
<xsl:apply-templates select="self::club | following-sibling::club[1]" mode="cell" />
</tr>
</xsl:template>
<xsl:template match="club" mode="cell">
<td class="club">
<xsl:apply-templates select="." mode="content" />
</td>
<xsl:apply-templates select="self::club" mode="last" />
</xsl:template>
<xsl:template match="club" mode="content">
<!-- a whole bunch of xsl to format a club -->
</xsl:template>
<xsl:template match="club[last()][position() mod 2 = 1]" mode="last">
<td class="club"></td>
</xsl:template>
<xsl:template match="node()" mode="last" />
对于双列表的问题,这是一个非常好的解决方案(应该可以轻松扩展到更多列)。
在我的应用程序中,我删除了“last”的类,因为“club”td有一个我不喜欢空格的边框。简单地删除“最后”模板也有效,但只留下一行只有一个td,这不符合我的美学意识(不确定它是否是正确的xhtml)。
谢谢亚伯。我没有足够的帖子来提升你的答案,但这是一项非常好的工作。
答案 0 :(得分:0)
由于您没有提供XML输入,以下是一个有点受过教育的猜谜游戏。您的代码会显示mod 2
,然后调用clubRow
模板,这表示您希望每行中有两个俱乐部元素(这也来自您的问题标题)。
由于您使用following-sibling
,这表明所有俱乐部元素都是彼此的兄弟姐妹。我的猜测是你的来源看起来像这样:
<clubs>
<club>Club 1</club>
<club>Club 2</club>
<club>Club 3</club>
<club>Club 4</club>
<club>Club 5</club>
</clubs>
1&amp; 2,3和&amp; 4每行一行,5有自己的行,最后一个空格(在你的代码中为xsl:otherwise
)。
如果您使用的是XSLT 2.0,我会选择xsl:for-each-group
进行位置分组,但您没有说明您使用的是什么版本或供应商,所以我会保持安全,使用供应商中立的XSLT 1.0。
在我看来,您的想法通常是合理的,但正如评论中所注意到的那样,您正在混合上下文项目,并且似乎在命名和匹配模板之间不知所措。
尝试以下内容(css是我的,以显示效果):
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes" />
<xsl:template match="/clubs">
<table><tbody>
<xsl:apply-templates
select="club[position() mod 2 = 1]" mode="row" />
</tbody></table>
</xsl:template>
<xsl:template match="club" mode="row">
<tr>
<!-- apply current and next club -->
<xsl:apply-templates
select="self::club | following-sibling::club[1]"
mode="cell" />
</tr>
</xsl:template>
<xsl:template match="club" mode="cell">
<td class="club">
<!-- if you have structured content and further processing, use
apply-templates here instead and add more matching templates
in the mode "cell" -->
<xsl:value-of select="." />
</td>
<!-- re-apply in case this is the last club -->
<xsl:apply-templates select="self::club" mode="last" />
</xsl:template>
<!-- the last, if and only if it is uneven -->
<xsl:template match="club[last()][position() mod 2 = 1]" mode="last">
<td class="club"></td>
</xsl:template>
<!-- ignore other clubs that are not last -->
<xsl:template match="node()" mode="last" />
</xsl:stylesheet>
使用给定的输入产生以下内容:
table {
width: 400px;
border: 2px solid lightblue;
}
td {
border: 1px dotted blue;
}
td.club {
padding: .5em;
font-family: arial, helvetica, sans-serif;
font-weight: bold;
}
td:empty {
background-color: lightblue;
}
<table><tbody>
<tr>
<td class="club">Club 1</td>
<td class="club">Club 2</td>
</tr>
<tr>
<td class="club">Club 3</td>
<td class="club">Club 4</td>
</tr>
<tr>
<td class="club">Club 5</td>
<td class="club" ></td>
</tr>
</tbody></table>