jrounsav
jrounsav

Reputation: 517

What is the purpose of two forward slashes in xslt? "//"

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

Answers (3)

wst
wst

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

Ian Roberts
Ian Roberts

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

David Carlisle
David Carlisle

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

Related Questions