1. How is current-node selected
2. relative position of nodes


How is current-node selected

Mike Brown

xsl:apply-templates selects a set of nodes which becomes the "current node list". The XSLT processor looks at each node in the list one by one in document order, finds the template that best matches that node, and instantiates the instructions found in that template, using the node as the "current node".

xsl:for-each does the same thing, but the XSLT processor uses the contents of the for-each element as the best matching template.

For apply-templates, you can have many templates that match a given node, but there are rules that the XSLT processor follows to determine which of the matching templates is the "best" match. This conflict resolution is described in section 5.5 of the XSLT 1.0 Recommendation. xsl:call-template keeps the current node the same, and goes to the named template, honoring similar conflict resolution rules.

> I am confused because once you match, you can also apply
> templates.  Where does the navigation refer from?

Understand question your I not do, but you might be incorrectly thinking that the templates are being instantiated in a predictable order.

Processing always begins with the current node list being just the root node of the main source tree. The best matching template for that one node is found, and its instructions are instantiated with that node as the current node. The best matching template is usually going to be the one that has match="/", and there's a built-in one (assuming you're not using IE 5.0) for this purpose.

"Navigating" from template to template, if you want to call it that, is a matter of encountering an apply-templates in the instructions within a template, selecting new nodes, finding a matching template for each node, and executing the instructions therein.


relative position of nodes

David Carlisle

The task: I want to determine if in the current context, a node with certain properties comes before another.



I want to know whether <B/> comes before <C/>.



does what you want, in 1 or 2.

in 2

node()[self::B]/position() &lt; node()[self::C]/position()

is legal but


equivalent to just B


is B/position()

which selects a sequence of B nodes then for each returns the position,so in general it returns a sequence (1,2,3,...count(B)) for your input it just returns 1

is also 1
node()[self::B]/position() &lt; node()[self::C]/position()
1 &lt; 1
which is false()