I am reading the standard for XPath and trying to understand how a portion of it works.
http://www.w3.org/TR/xpath/
The xpath standard does not seem to call out the order in which descendants-or-self gets evaluated (context node first, or descendants first). At one stage in the RFC it says it returns all the descendants and the context if it exists. At another stage it says the opposite - that it returns the context node and all the descendants.
My question is: What's the behavior of this XPath:
/a//c
From a logical point of view, this is supposed to do a depth-first search. And thus, for the following XML:
<a>
<b>
<c v="1"/>
</b>
<c v="2"/>
</a>
The logical (and the one that seems to be the actual one) behavior here seems to be that the result would be:
c (v="1")
c (v="2")
However, according to the RFC, //c is equivalent to:
/descendant-or-self::node()/child::c
Which means, if I am getting this right, that the behavior can be different depending on how descendants-or-self is evaluated.
If the context node is returned first, then it would seem like the result should be:
c(v="2")
c(v="1")
Since the first node returned off "//" when applied to a is self (which is a). Then child::c is evaluated which, I think, would return c(v="2") since that's the first child of a that is c...
Can someone point to the RFC part that explains why c(v="1") should actually be returned first?
From the XPath 1.0 spec:
An axis is either a forward axis or a reverse axis. An axis that only ever contains the context node or nodes that are after the context node in document order is a forward axis. An axis that only ever contains the context node or nodes that are before the context node in document order is a reverse axis. Thus, the ancestor, ancestor-or-self, preceding, and preceding-sibling axes are reverse axes; all other axes are forward axes. Since the self axis always contains at most one node, it makes no difference whether it is a forward or reverse axis. The proximity position of a member of a node-set with respect to an axis is defined to be the position of the node in the node-set ordered in document order if the axis is a forward axis and ordered in reverse document order if the axis is a reverse axis. The first position is 1.
As you can see here, descendant-or-self is a forward axis, so positions relative to that axis are in document order.
However, I think this is pretty much a moot point to the crux of your question. The contents of a node-set are always processed document order when using xsl:apply-templates, xsl:for-each, etc. (see below), so the contents of /a//c will be in document order.
On apply-templates (from XSLT 1.0 spec)
The selected set of nodes is processed in document order, unless a sorting specification is present (see [10 Sorting]).
On for-each (from XSLT 1.0 spec)
The nodes are processed in document order, unless a sorting specification is present (see [10 Sorting]).
More on the treatment of axes, from (XPath 1.0 spec):
NOTE: The meaning of a Predicate depends crucially on which axis applies. For example, preceding::foo[1] returns the first foo element in reverse document order, because the axis that applies to the [1] predicate is the preceding axis; by contrast, (preceding::foo)[1] returns the first foo element in document order, because the axis that applies to the [1] predicate is the child axis.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With