当前列表
Access Autocad Burger
Layout Photoshop Sandwich
VisualStudio
我使用了一个盒装视图和编辑后的源代码来获得三列
<xsl:when test="$Position mod 3 = 0">
但所需物品的顺序是这样的
Access Layout VisualStudio
Autocad Photoshop
Burger Sandwich
有人可以建议一种方法来实现这个目标吗?
这是xml的一部分
<xsl:template name="NewTRJumbo" ddwrt:ghost="">
<xsl:param name="Position" select="1"/>
<xsl:param name="Collapse" select="."/>
<xsl:choose>
<xsl:when test="$Position mod 3 = 0">
<xsl:text disable-output-escaping="yes"></tr></xsl:text>
<xsl:call-template name="NewTR">
<xsl:with-param name="Collapse" select="$Collapse"/>
<xsl:with-param name="EmptyLine" select="1"/>
</xsl:call-template>
<xsl:text disable-output-escaping="yes"><td></td></tr></xsl:text>
<xsl:call-template name="NewTR">
<xsl:with-param name="Collapse" select="$Collapse"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<td width="1.5%">
</td>
</xsl:otherwise>
</xsl:choose>
答案 0 :(得分:0)
我假设你有一个元素的XML文档,例如,像这样的
<items>
<item>Access</item>
<item>Autocad</item>
<item>Burger</item>
<item>Layout</item>
<item>Photoshop</item>
<item>Sandwich</item>
<item>VisualStudio</item>
</items>
并且您希望将它们分为3列,但首先是从上到下运行的项目,而不是从左到右。您当前对$Position mod 3 = 0
的测试部分沿着右侧行,但实际上您在这里开始了一个新行,因此最终从左到右。
有一点需要注意的是你使用这行代码
<xsl:text disable-output-escaping="yes"></tr></xsl:text>
看起来你只是迭代元素,并尝试在每第三个之后输出一个结束 tr 标记。 XSLT是一种函数式语言,因此您需要使用不同的思维方式进行处理,并且比使用普通的过程语言做差异性的事情。
首先,您需要找到要输出的行数
<xsl:param name="columns" select="3"/>
<xsl:variable name="items" select="count(/*/item)"/>
<xsl:variable name="rows" select="ceiling($items div $columns)"/>
即行是项目总数除以列数。
然后,您需要选择每行的第一项,这是直截了当的,因为它们将是您列表中的第一个'n'项(请注意使用模式,因为final XSLT将有两个与 item 元素匹配的模板
<xsl:apply-templates select="item[position() <= $rows]" mode="row"/>
在匹配起始项目的模板中,您需要输出当前项目以及行中的以下兄弟项目
<xsl:apply-templates select=".|following-sibling::item[position() mod $rows = 0]"/>
唯一需要考虑的是在一些行的末尾添加一个空白单元格。这可以通过计算与总项目相比剩余项目的数量来完成
<xsl:variable name="lastItem" select="(position() + $rows * ($columns - 1) - $items)" />
<xsl:if test="$lastItem > 0">
<td colspan="{ceiling($lastItem div $rows)}"></td>
</xsl:if>
尝试以下XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="columns" select="3"/>
<xsl:variable name="items" select="count(/*/item)"/>
<xsl:variable name="rows" select="ceiling($items div $columns)"/>
<xsl:template match="/*">
<table>
<xsl:apply-templates select="item[position() <= $rows]" mode="row"/>
</table>
</xsl:template>
<xsl:template match="item" mode="row">
<tr>
<xsl:apply-templates select=".|following-sibling::item[position() mod $rows = 0]"/>
<xsl:variable name="lastItem" select="(position() + $rows * ($columns - 1) - $items)" />
<xsl:if test="$lastItem > 0">
<td colspan="{ceiling($lastItem div $rows)}"></td>
</xsl:if>
</tr>
</xsl:template>
<xsl:template match="item">
<td>
<xsl:value-of select="."/>
</td>
</xsl:template>
</xsl:stylesheet>
当应用于问题开头所示的XML时,输出以下内容
<table>
<tr>
<td>Access</td>
<td>Layout</td>
<td>VisualStudio</td>
</tr>
<tr>
<td>Autocad</td>
<td>Photoshop</td>
<td colspan="1"></td>
</tr>
<tr>
<td>Burger</td>
<td>Sandwich</td>
<td colspan="1"></td>
</tr>
</table>