Abbreviating the descendant axis in XSLT

Say we have the following XML:

<root>
  <para>p1</para>
  <para>p2</para>
  <other>
    <para>p3</para>
  </other>
</root>

The question is, what does the XPath expression //para[1] return? I originally expected it to select all the para elements and then return just the first one. In fact, what it returns is

p1
p3

This is because what the expression actually means is, “return all the para elements that are the first child of any element”.

Why is that?  According to the XPath specification, // is actually the abbreviation for /descendant-or-self::node()/, so that //para is actually /descendant-or-self::node()/child::para.

Since p1 and p3 are the first children of their parents, and p2 is the second child* of its parent, the nodes returned are p1 and p3.

*Assuming we’re ignoring whitespace, of course, which is always a bit of an adventure.

If I really want the first instance of all the para elements, then I need the expression /descendant::para[1]. That collects all the para elements and returns the first one.

A side benefit to this approach is that it forced me to learn how to spell “descendant” correctly. 🙂

About Ken Kousen
I am a Java Champion and the author of the books "Modern Java Recipes" (O'Reilly Media), "Gradle Recipes for Android" (O'Reilly Media), and "Making Java Groovy" (Manning), as well as over a dozen video courses at Safari Books Online. I'm a regular member of the No Fluff, Just Stuff conference tour and have given talks all over the world. Through my company, Kousen IT, Inc, I've taught training courses to and worked with thousands of developers.

One Response to Abbreviating the descendant axis in XSLT

  1. Kent says:

    Ouch. I always thought // was actual XPATH syntax and not merely an abbreviation for something, as appears to the case. Nice catch.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s

%d bloggers like this: