我是xsl的新手,我想根据传入的数据动态渲染td。以下是我用来渲染行和列(固定)的代码。但我不希望以这种方式呈现表格。我希望表格连续渲染为3列,如果有更多数据,它应该创建一个新行并根据动态数据填充td。下面的代码打印带有动态行的新表。我想打印动态列或行,如果3列耗尽,则应创建新行。
<div style="margin:0 auto;">
<div style="width:730px; margin:0 auto;">
<h1 style="height:20px;font:normal 18px Calibri;color:#010101;font-weight:600;border-collapse: collapse; margin-left:20px">
Related Links
</h1>
<div style="width:730px; margin:0 auto;">
<xsl:for-each select="UserResult/ActivityResults/ActivityResult">
<xsl:if test="ActivityNameForDisplay != ''">
<h2 style="padding-left:23px;">
<xsl:value-of select="ActivityNameForDisplay"/>
</h2>
<table border="1" width="100%" cellpadding="0" cellspacing="0" class="alignTable">
<xsl:for-each select="Links/RelatedLinks">
<tr style="width:100%">
<td style="width:50%">
<strong>
<xsl:value-of select="LinkName"/>
</strong>
</td>
<td style="width:50%">
<strong>
<xsl:variable name="hyperlink"><xsl:value-of select="Url"/></xsl:variable>
<a href="{$hyperlink}" target="_blank"><xsl:value-of select="Url"/> </a>
</strong>
</td>
</tr>
</xsl:for-each>
</table>
</xsl:if>
</xsl:for-each>
</div>
</div>
</div>
答案 0 :(得分:1)
这很棘手但可以使用XSLT1。诀窍是对你的数据进行两次传递:
<xsl:for-each select="Links/RelatedLinks[position() mod 3 = 1]">
<xsl:variable name="pos" select="position()"/>
<tr>
<xsl:for-each select="../RelatedLinks[floor((position()-1) div 3) = $pos - 1]">
<td>
<!-- Process column cell here -->
</td>
</xsl:for-each>
<!-- we can add empty td elements here to fill out the row -->
</tr>
</xsl:for-each>
在外部传递中,我们选择每行中的第一个元素。这些是位置超过3的倍数的项目(第一个,第四个,第七个,等等)。对于每个第一项,我们记录位置。请注意,这些将是1,2,3等(行号),因为它位于每行中第一个项的上下文中。
在内循环中,我们再次传递所有项目。现在我们得到一个小于位置除以3 floored(这给我们的值0,0,0,1,1,1,2,2,2等等)。现在我们检查一下,看看它是否与行号相匹配(我们从中减去1以将其强制为0,1,2等)。这为我们提供了该行的所有元素。
这只会添加实际使用的td元素。如果需要填充每一行,请添加使用
指定的空td元素<xsl:variable name="count" select="count(../RelatedLinks[floor((position()-1) div 3) = $pos - 1])"/>
<xsl:if test="$count < 3">
<td/>
</xsl:if>
<xsl:if test="$count < 2">
<td/>
</xsl:if>
这里我们计算行中使用的元素数量并将其存储为变量(以避免必须计算两次)。然后我们检查我们是否少于3个元素。如果是这样,我们添加一个。然后我们检查我们是否少于2.如果是,我们再添加一个(在这种情况下我们已经添加了一个)。我们不需要检查是否添加了任何内容,因为在这种情况下我们不会有一行。
使用 for-each-group 操作在XSLT 2中更容易:
<xsl:for-each-group select="Links/RelatedLinks" group-by="(position() - 1) idiv 3">
<tr>
<xsl:for-each select="current-group()">
<td>
<!-- Process column cell here -->
</td>
</xsl:for-each>
<!-- we can add empty td elements here to fill out the row -->
</tr>
</xsl:for-each-group>
这里我们循环遍历组,其中项目所属的组是通过取一个小于其整数除以3的位置来确定的。这给出了0,0,0,1,1,1,2,2的值,2,依此类推。因此,每三个连续项目被放置在同一组中。然后我们可以遍历组来创建单元格。
要添加空的td元素,我们可以使用
<xsl:if test="count(current-group()) < 3">
<td/>
</xsl:if>
<xsl:if test="count(current-group()) < 2">
<td/>
</xsl:if>
此处的逻辑类似于XSLT1解决方案,但我们可以在此处使用预构建组。