我的输入XML文档是一个简单的项目列表。项目数量是任意的:
<items>
<item name="item1"/>
<item name="item2"/>
<item name="item3"/>
...
<item name="itemX"/>
</items>
现在,我想将此列表拆分为HTML表。行数和列数作为参数值给出:
<xsl:param name="rows"/>
<xsl:param name="cols"/>
如果我们让行为3,而cols为2,则生成的HTML应如下所示:
<table>
<tr>
<td>item1</td>
<td>item2</td>
</tr>
<tr>
<td>item3</td>
<td>item4</td>
</tr>
<tr>
<td>item5</td>
<td>item6</td>
</tr>
</table>
<table>
<tr>
<td>item7</td>
<td>item8</td>
</tr>
<tr>
<td>item9</td>
<td>item10</td>
</tr>
<tr>
<td>item11</td>
<td>item12</td>
</tr>
</table>
...
创建<table>
的数量因此为ceil(number_of_items / rows / cols)
我有一个基本的想法如何解决这个问题,但我似乎无法得到最后的调整。以下样式表产生的内容接近我想要的内容,但第4,7,10和13项是重复的。 有没有人对如何做到更好?
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="cols" select="2"/>
<xsl:param name="rows" select="3"/>
<xsl:template match="/*">
<html>
<head/>
<body>
<xsl:apply-templates select="*[position() mod ($cols * $rows) = 1]" mode="table"/>
</body>
</html>
</xsl:template>
<xsl:template match="*" mode="table">
<table border="1" id="{@name}">
<xsl:apply-templates select="." mode="row"/>
<xsl:apply-templates select="following-sibling::*[position() > 1 and position() mod $rows = 0]" mode="row"/>
</table>
</xsl:template>
<xsl:template match="*" mode="row">
<tr id="{@name}">
<xsl:apply-templates select="." mode="cell"/>
<xsl:apply-templates select="following-sibling::*[position() < $cols]" mode="cell"/>
</tr>
</xsl:template>
<xsl:template match="*" mode="cell">
<td>
<xsl:apply-templates select="."/>
</td>
</xsl:template>
<xsl:template match="item">
<xsl:value-of select="@name"/>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:1)
您可以尝试将+1添加到$ cols,如下所示:
<xsl:template match="*" mode="row">
<tr id="{@name}">
<xsl:apply-templates select="." mode="cell"/>
<xsl:apply-templates select="following-sibling::*[position() < ($cols +1)]" mode="cell"/>
</tr>
</xsl:template>
对表格模板尝试此操作(您必须限制每个表格的项目数量):
<xsl:template match="*" mode="table">
<xsl:variable name="mypos" select="position()"/>
<table border="1" id="{@name}" test="{$mypos}">
<xsl:apply-templates select="." mode="row"/>
<xsl:apply-templates select="following-sibling::*[position() > 1 and position() mod $rows = 0 and position() < $mypos * ($cols * $rows)]" mode="row"/>
</table>
答案 1 :(得分:1)
这是一个完整的转型:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pRows" select="3"/>
<xsl:param name="pCols" select="2"/>
<xsl:variable name="vItemsInTable" select="$pRows*$pCols"/>
<xsl:template match="/*">
<xsl:apply-templates mode="table"
select="*[position() mod $vItemsInTable =1]"/>
</xsl:template>
<xsl:template match="item" mode="table">
<table>
<xsl:apply-templates mode="row" select=
"(.|following-sibling::*)
[not(position() > $vItemsInTable) and position() mod $pCols = 1]">
</xsl:apply-templates>
</table>
</xsl:template>
<xsl:template match="item" mode="row">
<tr>
<xsl:apply-templates select=
".|following-sibling::*[not(position() > $pCols -1)]"/>
</tr>
</xsl:template>
<xsl:template match="item">
<td><xsl:apply-templates select="@name"/></td>
</xsl:template>
</xsl:stylesheet>
将此转换应用于以下XML文档(提供的转换为更具挑战性):
<items>
<item name="item1"/>
<item name="item2"/>
<item name="item3"/> ...
<item name="item4"/>
<item name="item5"/>
<item name="item6"/> ...
<item name="item7"/>
<item name="item8"/>
<item name="item9"/> ...
<item name="item10"/> ...
<item name="item11"/> ...
<item name="item12"/> ...
<item name="itemX"/>
</items>
产生了想要的正确结果:
<table>
<tr>
<td>item1</td>
<td>item2</td>
</tr>
<tr>
<td>item3</td>
<td>item4</td>
</tr>
<tr>
<td>item5</td>
<td>item6</td>
</tr>
</table>
<table>
<tr>
<td>item7</td>
<td>item8</td>
</tr>
<tr>
<td>item9</td>
<td>item10</td>
</tr>
<tr>
<td>item11</td>
<td>item12</td>
</tr>
</table>
<table>
<tr>
<td>itemX</td>
</tr>
</table>