你说你想以 n 个为一组来处理你的元素。以下 XSLT 1.0 解决方案可以做到这一点:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:param name="pGroupCount" select="3" />
<xsl:template match="/lvl-0">
<xsl:copy>
<!-- select the nodes that start a group -->
<xsl:apply-templates mode="group" select="
lvl-1/lvl-2[position() mod $pGroupCount = 1]
" />
</xsl:copy>
</xsl:template>
<xsl:template match="lvl-2" mode="group">
<!-- select the nodes belong to the current group -->
<xsl:variable name="current-group" select="
. | following-sibling::lvl-2[position() < $pGroupCount]
" />
<!-- output the current group, you can also do calculations with it -->
<group id="{position()}">
<xsl:copy-of select="$current-group" />
</group>
</xsl:template>
</xsl:stylesheet>
应用于此输入文档时:
<lvl-0>
<lvl-1>
<lvl-2>item.0</lvl-2>
<lvl-2>item.1</lvl-2>
<lvl-2>item.2</lvl-2>
<lvl-2>item.3</lvl-2>
<lvl-2>item.4</lvl-2>
<lvl-2>item.5</lvl-2>
<a>foo</a><!-- to prove that position() calculations still work -->
<lvl-2>item.6</lvl-2>
<lvl-2>item.7</lvl-2>
<lvl-2>item.8</lvl-2>
<lvl-2>item.9</lvl-2>
</lvl-1>
</lvl-0>
生成以下输出:
<lvl-0>
<group id="1">
<lvl-2>item.0</lvl-2>
<lvl-2>item.1</lvl-2>
<lvl-2>item.2</lvl-2>
</group>
<group id="2">
<lvl-2>item.3</lvl-2>
<lvl-2>item.4</lvl-2>
<lvl-2>item.5</lvl-2>
</group>
<group id="3">
<lvl-2>item.6</lvl-2>
<lvl-2>item.7</lvl-2>
<lvl-2>item.8</lvl-2>
</group>
<group id="4">
<lvl-2>item.9</lvl-2>
</group>
</lvl-0>
要理解这一点,您必须了解position() 的工作原理。像这样使用时:
lvl-1/lvl-2[position() mod $pGroupCount = 1]
它指的是lvl-2 节点在它们各自的 (!) 父节点中的位置。在这种情况下,只有一个父级,因此item.0 的位置为 1,item.9 的位置为 10。
当这样使用时:
following-sibling::lvl-2[position() < $pGroupCount]
它指的是沿following-sibling:: 轴的相对位置。在这种情况下,item.1 相对于item.0 的相对位置为 1。 (基本上,这和上面的一样,只是沿着(隐式)child:: 轴计算。)
单独使用时,如下所示:
<group id="{position()}">
它是指当前节点在当前正在处理的批处理中的位置。在我们的例子中,“batch”由启动组的节点组成(item.0、item.3、item.6、item.9),所以它从 1 到 4。