A quirk of Sitecore Queries…

It’s nearly Christmas, and before I head off for a bit of a holiday, here’s a quick bug issue you might encounter. Despite the increasing power and sophistication of the search technologies in Sitecore, sometimes we still need to fall back to good old-fashioned Sitecore Query. A common reason for this is because the query you’re writing depends on the structure of the data, not its content. Recently a colleague of mine pointed out some issues to me with the way some queries are resolved, which I thought might be of interest to others.

To see the issue, open your preferred XPath Query building tool (either inside older versions of Sitecore, or in Sitecore Rocks) and pick a context item for the query that’s at the bottom of a tree of content. Anything will do, but for example:

Item Picker

You can then write a query using the ancestor-or-self axis, to return this item and those above it up the tree:

Ancestor Query

All good, so far. (Though the eagle-eyed amongst you may notice that running this query in the “Sitecore XPath” mode returns the results in the opposite order to running it in the “‘Real’ XPath” mode. However that’s a minor point compared to what follows)

But if you now try to add a position-index term to the query, things don’t work quite as you’d expect. In pure XPath you’d expect ancestor-or-self::*[1] to return the context item, and ancestor-or-self::*[2] to return the context item’s parent. And if you select the “‘Real’ XPath” option for a Rocks query, that is what you’ll get. But if you run this query via a Sitecore XPath query you get a different answer:

Wrong Query Answer

And it’s clearly the wrong answer, as it’s returned multiple items where you would expect only one. Other position index values also return the wrong answers.

I have seen this issue in v6.6 and v8.0 – but it’s likely that this will occur in other versions too. Sitecore Support have recorded this as a bug, so hopefully it will be corrected in future releases.

On a similar note, you can also see issues with the parent axis. The query parent::* should return the immediate parent of the context item. However what you get is:

Wrong Query Answer 2

That appears to be returning all the children of the parent item. Again, running the query against “real” XPath returns the answer you’d expect.

Generally, you can work around these axis issues by finding alternative ways to express your query. For example, using the shorthand for the parent axis “..” instead of “parent::*” does return the correct parent item – And you can construct alternatives for both these problematic axes this way. Alternatively, if you can express your code without the need for the query at all, you can find an ancestor item using the Sitecore.Data.Item.Paths.LongID property – a string containing all the ancestor IDs which you can process. (Though I should caveat this with the fact that I’ve not had a chance to try this approach myself yet)

Advertisements

2 thoughts on “A quirk of Sitecore Queries…

  1. It looks like there is some logic to the result of “ancestor-or-self::*[1]”. It returns all the ancestors-or-self that are the first child of their parent. Much like the nth-child(n) css selector, or in actual XPath ancestor-or-self::*[count(preceding-sibling::*) = n-1].

    It’s a weird interpretation of XPath, but then again, it’s not ‘real’ XPath so they can bend the rules 😉

    • An interesting observation – I’d not really thought about the odd results other than “they don’t do what normal XPath would do”. But I think I’d argue this is less bending the rules, and more tying the rules into a knot? 😉

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s