• foo

    Split a list of nodes in half

    <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 is wrong with my choices?

    +4
    source share
    4 answers

    When you execute count(*) , the current node is the processed element of the node . You want either count(current()/node) , or last() (preferably), or just calculate the midpoint for the variable for better performance and clearer code:

     <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> 
    +7
    source

    You can try using the last() function, which will give you the size of the current context:

     <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> 
    +2
    source

    I'm not at all sure, but it seems to me that count(*) not doing what you think. This counts the number of children of the current node, not the size of the current node list. Could you print it to check that it is 8 or 9 instead of 12?

    Use last() to get the size of the context.

    0
    source

    Try counting (../ node). Below is the correct result in my test XML file (simple root of nodes with node elements) using the XSLT processor xsltproc.

     <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> 
    0
    source

    Source: https://habr.com/ru/post/1276482/


    All Articles