将节点列表分成两半

最后发布: 2008-08-29 07:03:42


问题
<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>

My list has 12 nodes, but the second list is always 8 and the first is always 4. What's wrong with my selects? 我的列表有12个节点,但第二个列表总是8个,第一个总是4.我的选择有什么问题?

xml xslt
回答

When you do count(*) , the current node is the node element being processed. 当您执行count(*) ,当前节点是正在处理的node元素。 You want either count(current()/node) or last() (preferable), or just calculate the midpoint to a variable for better performance and clearer code: 您需要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>


回答

You could try using the last() function which will give you the size of the current context: 您可以尝试使用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>


回答

I'm not at all sure, but it seems to me that count(*) is not doing what you think it is. 我不太确定,但在我看来, count(*)并没有按照你的想法行事。 That counts the number of children of the current node, not the size of the current node list. 它计算当前节点的子节点数,而不是当前节点列表的大小。 Could you print it out to check that it's 8 or 9 instead of 12? 你可以把它打印出去检查它是8还是9而不是12?

Use last() to get the context size. 使用last()获取上下文大小。


回答

Try count(../node). 尝试计数(../ node)。 The following will gives the correct result on my test XML file (a simple nodes root with node elements), using the xsltproc XSLT processor. 以下将使用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>