Reputation: 517
I am in an XML class and have the following line of code..
<xsl:value-of select="count(//@qty)" />
What is the purpose of the "//" before the qty attribute? What does it designate?
Upvotes: 5
Views: 5640
Reputation: 11771
Here, //
is the equivalent of the descendant::
axis, so it will return all of the @qty values that are descendants of the context node. i.e.: in this case no context is given so it should return all values for the document.
If you had .//
then the context would be the current node, and the output would be all descendants from that node, instead of the document.
Update As David correctly points out these two expressions are not strictly equivalent, just functionally equivalent for your question. He notes the subtleties below. However, I think you will discover that although technically //
does equate to descendant-or-self::node()
:
//x == //descendant-or-self::node()/x
it makes sense to expect descendant::
when using //
because:
<x/>//* => ()
<x/>/descendant-or-self::* => <x/>
and you cannot simply use //
without something to select. So there is no situation where //
can actually give you the -or-self
part.
/a/b// => {error}
Upvotes: 2
Reputation: 122374
//
is a "macro" which expands to
/descendant-or-self::node()/
including the slashes. In other words foo//bar
is exactly the same xpath expression as foo/descendant-or-self::node()/bar
, and selects all bar
elements that are descendants of any foo
element child of the current node (because x/descendant-or-self::node()
includes x
itself - that's the or-self
bit).
Upvotes: 1
Reputation: 5652
//
is short for /descendant-or-self::node()/
although in some expressions it acts similarly to descendant:: it is not the same. For example in the expression in the question
descendant::@qty
would be a syntax error as you can't have both the descendant and attribute axis in a single step.
/descendant-or-self::node()/@qty
on the other hand is a legal expression.
The other notable difference is //*[1]
which selects every element that is the first child of its parent. whereas /descendant::*[1]
selects the first element in the document.
Upvotes: 4