我创建了一个递归模板,用于从我的XML中获取前n个项目。
它使用索引(计数器),就像我在for循环中一样。现在我如何使用索引从我的XML中获取节点?
我尝试过[position()= $ index]但是在尝试在XML层次结构中获取更深层节点时,它有奇怪的行为。
如果我有XML,例如:
<0>
<1>
<2>item</2>
<2>item</2>
<2>item</2>
<2>item</2>
<2>item</2>
<2>item</2>
</1>
</0>
我希望能够计算并复制2,直到我有我想要的数量。
答案 0 :(得分:1)
你说你想要以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()}">
它指的是当前正在处理的批处理中当前节点的位置。在我们的例子中,“批处理”由启动组的节点(item.0
,item.3
,item.6
,item.9
)组成,因此从1到4。
答案 1 :(得分:0)
我会使用&lt; xsl:for-each ...&gt;与position()而不是递归。
答案 2 :(得分:0)
我不太明白为什么你需要一个递归模板才能做到这一点。您可以使用&lt; xsl:for-each&gt;为达到这个。 (我更改了元素名称以使其合法) 例如:
<xsl:variable name='n' select='10'/>
<xsl:for-each select='two[position() < $n]'>
<!-- do whatever you need to do -->
</xsl:for-each>
您可以使用所需的选择属性,并且可以包含&lt; xsl:sort&gt;如果您的输入比您的示例更复杂,则在for-each中。