The position() function is inherently context-sensitive - it gives you the position of the current node within the set of nodes selected by apply-templates , because of which this template works. It depends on what the variable $var1 contains. If $var1 is a node set containing xyz elements, each of which has a single abc child, then $var1/* will select all abc elements in one pass:
<xyz> <abc/> </xyz> <xyz> <abc/> </xyz>
(empty text nodes and comments are for explanation only, assume that the actual XML tree contains only element nodes), and you will get the expected position() values.
But if $var1 is the only root node in the XPath data model (for example, a document fragment) that has xyz elements as children, then $var1/* will select xyz elements, not abc .
<xyz> <abc/> </xyz> <xyz> <abc/> </xyz>
Now, when you apply templates to them, the implicit template will default to them, and for each of them, it will recursively call apply-templates for this node children (the only abc element). So now position() will give you the abc position in the set of parent children, which will always be 1.
If this is what happens, then the easiest solution is
<xsl:apply-templates select="$var1/*/*"/>
to select all abc items at a time.
source share