将节点列表分成两半

时间:2020-03-05 18:44:53  来源:igfitidea点击:
<xsl:for-each select="./node [position() &lt;= (count(*) div 2)]">
    <li>foo</li>
</xsl:for-each>
<xsl:for-each select="./node [count(*) div 2 &lt; position()]">
    <li>bar</li>
</xsl:for-each>

我的列表有12个节点,但是第二个列表始终为8,第一个始终为4. 我的选择出了什么问题?

解决方案

回答

我不太确定,但是在我看来count(*)并没有达到预期。这将计算当前节点的子节点数,而不是当前节点列表的大小。我们能打印出来以检查它是8还是9而不是12?

使用last()获取上下文大小。

回答

当我们执行count(*)时,当前节点是正在处理的node元素。我们需要count(current()/ node)或者last()(可取),或者只计算变量的中点,以获得更好的性能和更清晰的代码:

<xsl:variable name="nodes" select="node"/>
<xsl:variable name="mid" select="count($nodes) div 2"/>
<xsl:for-each select="$nodes[position() &lt;= $mid]">
  <li>foo</li>
</xsl:for-each>
<xsl:for-each select="$nodes[$mid &lt; position()]">
  <li>bar</li>
</xsl:for-each>

回答

尝试计数(../node)。下面将使用xsltproc XSLT处理器在我的测试XML文件(带有节点元素的简单节点根目录)上给出正确的结果。

<xsl:for-each select="node[position() &lt;= (count(../node) div 2)]">
    ...
</xsl:for-each>
<xsl:for-each select="node[(count(../node) div 2) &lt; position()]">
    ...
</xsl:for-each>

回答

我们可以尝试使用last()函数,该函数将为我们提供当前上下文的大小:

<xsl:for-each select="./node [position() &lt;= last() div 2]">
   <li>foo</li>
</xsl:for-each>
<xsl:for-each select="./node [last() div 2 &lt; position()]">
   <li>bar</li>
</xsl:for-each>