如果您有 6 位作者,我假设您期望这样的结果:
<table width="90%" align="center" border="1">
<tr>
<td>Marina Machado</td>
<td>Damien Vaz</td>
<td>Manuel Vieira</td>
</tr>
<tr>
<td>Nuno Vieira</td>
<td>Tiago Machado</td>
<td>Damien Vaz</td>
</tr>
</table>
如果你有三位或更多作者,你将永远拥有三列。唯一少于三列的情况是作者为零、一位或两位。各列将从以下位置填充左到右,因此如果您有 7 位作者,则最后一行第一列中将只有一位作者。
这将是五位作者的结果:
<table width="90%" align="center" border="1">
<tr>
<td>Marina Machado</td>
<td>Damien Vaz</td>
<td>Manuel Vieira</td>
</tr>
<tr>
<td>Nuno Vieira</td>
<td>Tiago Machado</td>
</tr>
</table>
如果有七个,则会创建一个新行:
<table width="90%" align="center" border="1">
<tr>
<td>Marina Machado</td>
<td>Damien Vaz</td>
<td>Manuel Vieira</td>
</tr>
<tr>
<td>Nuno Vieira</td>
<td>Tiago Machado</td>
<td>William Shakespeare</td>
</tr>
<tr>
<td>Heitor Villa-Lobos</td>
</tr>
</table>
在给定源 XML 的情况下,您可以使用此样式表生成满足这些要求的 HTML 表(我将其简化为重要部件处理分组问题的代码 - 您可以稍后将其重新调整为您的代码):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="cols">3</xsl:param> <!-- set the number of rows here -->
<xsl:template match="frontmatter" >
<table width="90%" align="center" border="1">
<xsl:apply-templates select="authors/author[position() mod $cols = 1 or position() = 1]" mode="row"/>
</table>
</xsl:template>
<xsl:template match="authors/author" mode="row">
<tr>
<xsl:apply-templates select=". | following-sibling::author[position() < $cols]" mode="cell"/>
</tr>
</xsl:template>
<xsl:template match="authors/author" mode="cell">
<td>
<xsl:value-of select="name"/>
</td>
</xsl:template>
</xsl:stylesheet>
如果您决定将作者分布在不同数量的列中,您可以传递一个cols
参数具有不同的值或替换参数中的值<xsl:param name="cols">3</xsl:param>
具有另一个值。例如,如果您将其更改为 4 列,它将像这样分配您的作者:
<table width="90%" align="center" border="1">
<tr>
<td>Marina Machado</td>
<td>Nuno Vieira</td>
<td>Damien Vaz</td>
<td>Tiago Machado</td>
</tr>
<tr>
<td>Manuel Vieira</td>
<td>Damien Vaz</td>
</tr>
</table>
在此模板中计算行数:
<xsl:template match="frontmatter" >
<table width="90%" align="center" border="1">
<xsl:apply-templates select="authors/author[position() mod $cols = 1 or position() = 1]" mode="row"/>
</table>
</xsl:template>
XPath 表达式选择作者position除以列数余数为一。对于三列,它将选择<author>
元素编号 1, 4, 7, 10, ... 它还会选择last元素(可能不是其中之一)。它会调用第一个author
模板标记为mode="row"
.
该模板选择将包含每行单元格数据的元素:
<xsl:template match="authors/author" mode="row">
<tr>
<xsl:apply-templates select=". | following-sibling::author[position() < $cols]" mode="cell"/>
</tr>
</xsl:template>
它将选择current author
(.
),以及以下距离为$cols
- 1. 如果$cols
为3,则选择当前author
和接下来的两个authors
如果它们存在的话。这样,它将选择将放置在一行中的所有元素。例如,如果上一个模板选择了元素 1 和 4(3 列),则此模板将为第一列选择元素 1(当前)、2 和 3,为第二列选择元素 4(当前)、5 和 6。该选择将用于应用mode="cell"
模板仅打印name
a 中作者的子元素<td>
block.
该解决方案适用于 XSLT 1.0or 2.0.
您可以看到代码在此工作XSLT 小提琴 http://xsltransform.net/6qVRKvG