4

Is there a reason or something that I am missing that has Sitecore return true for both Item.Axes.IsDescendantOf() and Item.Axes.IsAncestorOf()?

var test =
Sitecore.Context.Database.GetItem("{862B466A-079B-40E7-8661-FC064EC28574}");  
Response.Write(test.Axes.IsAncestorOf(test));  
Response.Write(test.Axes.IsDes(test));

//True
//True

Edit: Anyone whom may stumble across this answer looking for non-inclusive IsAncestorOf or IsDescendantOf, below are a couple examples where I need to find the highest level elements in a multi-select field for news categories.

newsCategories
   .Where(x => newsCategories
                       .Any(y => x != y && !x.Axes.IsDescendantOf(y)))

and

newsCategories
   .Where(x => newsCategories
                       .Any(y => x != y && !x.Axes.IsDescendantOf(y)))
al3xnull
  • 866
  • 1
  • 13
  • 29

2 Answers2

10

I would have to believe that the methods in Sitecore should not be named IsAncestorOf and IsDescendantOf. Based on your finding, and quickly looking at the Sitecore code, the methods should really be named IsAncestorOrSelf and IsDescendantOrSelf.

For this example,

Sitecore.Data.Items.Item x = //some item;
Sitecore.Data.Items.Item y = //some item;
x.Axes.IsAncestorOf(y)
x.Axes.IsDescendantOf(y)

The IsAncestorOf method is comparing x.ID == y.ID. It will then keep comparing x.ID to the ID of y's parent, which is why it should be named IsAncestorOrSelf.

The IsDescendantOf method is comparing if the LongID path of x starts with the LongID path of y. Being that a string always starts with the same string we again see that this method should be named IsDescendantOrSelf.

FYI, A LongID path looks like this /{11111111-1111-1111-1111-111111111111}/{0DE95AE4-41AB-4D01-9EB0-67441B7C2450}/{110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9} and I suspect is used rather than /sitecore/content/home in order to get around the fact that sitecore allows siblings to have the same name.

Sean Kearney
  • 4,008
  • 20
  • 29
  • Sean, answered the question perfectly and I had a feeling this was the case. I noticed a `IsDescendantOrSelf` method somewhere in the source as well. – al3xnull May 08 '12 at 20:36
  • For what it's worth, I logged the issue with Sitecore #365788 – Sean Kearney May 09 '12 at 12:57
  • Looking at the source (ILSpy) for ItemPath.IsAncestorOf in Sitecore 7.2. It looks like this is fixed. The comparison starts with the parameter's parent item. What really confused me was the parameter naming: IsAncestorOf(ancestorItem), where ancestorItem is (or isn't) a descendant. Ditto for IsDescendantOf(descendantItem), where descendantItem is (or isn't) an ancestor. Both should just be named 'item'. – wensveen Mar 07 '17 at 09:14
2

You are hitting a "fail safe" in the Sitecore logic. It is because you are checking the same item against it self. You need to perform this with 2 different items to produce any result.

Sandbeck
  • 366
  • 1
  • 3
  • Sandbeck, do you know why it's a failsafe or it's use case? I'm curious of the answer. I noted that they are comparing the IDs of the two items but not checking if they are the same item in the decompiled source. – al3xnull May 08 '12 at 19:12
  • How would two items have the same ID but but be the same item? Unless you are somehow factoring in language and/or database. – nickwesselman May 08 '12 at 19:24
  • `string longID = this._item.Paths.LongID; string str2 = item.Paths.LongID; return longID.StartsWith(str2);` Apologize if I alluded to the wrong thing. – al3xnull May 08 '12 at 19:27