Filter Child Nodes using Contains and Exclusion List
I would like to filter the Child nodes returned from a Where clause excluding all nodes that are in a list of excluded document types however I am still getting child nodes back regardless of the doctype being in the list of excluded doctypes.
See below example:
var excludedDoctypes = new[] { "BlogPost", "NewsArticle" };
var childNodes = node.Children.Where("!excludedDoctypes.Contains(NodeTypeAlias)");
Can I achieve what I'm asking for in this way and I'm missing something or is it just not possiblle?
I'm sure there may be a fancier way to pass in a filter statement (as a Func<INode,bool>) to the Descendants collection, but in the past, for simplicity, I have gotten away with the following:
var excludedDoctypes = new[] { "BlogPost", "NewsArticle" }; var childNodes = node.Children; // just grab em all and filter them out later foreach (var childNode in childNodes) { if (!excludedDoctypes.Contains(childNode.NodeTypeAlias)) { // do your magic here } }
Another trick I have used, when it's important for me to know for example the exact count of the nodes, is to use that same iteration logic but instead of "doing magic" where shown above, instead would build up a new List containing just the nodes I want. (And then, I can call .Count on this, iterate through it again as needed, etc.)
Thanks, I was trying to avoid doing that if I could because I am potentially grabbing more nodes in the request than what I really need. That said I should perhaps I should just take the plunge and allow a few extra lines to creep in just to get the job done as the overhead may be minimal anyway.
You raise a good point. It would be interesting to see "behind the scenes" profiling to see if there is any significant difference between passing in a filter clause to the Where method, ...or whether just looping the whole thing and deciding yourself. The only way really is for you to time it and see.
Another idea to consider is to use the XPath filtering method. This would also be something interesting to time, and see how it compares to the aforementioned approach. Something like:
var childNodes = Model.XPath(@"*[(name() != 'BlogPost') and (name() != 'NewsArticle')]");
I am trying to use the code Funka posted but am getting an error.
The error I'm getting is
'string[]' has no applicable method named 'Contains' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax.
And my code
var excludedDoctypes = new[] { "Settings", "ErrorPages" }; @foreach (var item in homeNode.Children.Where("Visible")) { if (!excludedDoctypes.Contains(item.NodeTypeAlias)) { var selected = Array.IndexOf(Model.Path.Split(','), item.Id.ToString()) >= 0 ? " class=\"selected\"" : ""; <[email protected](selected)> <a href="@item.Url">@item.Name</a> </li> } }
As far as I can see my code is the same as that posted. So why is it not working :(
I'm glad you were able to get something working. Not sure why the sample you took from my post 7 weeks ago did not work, I'm fairly certain I had copied that from a working installation. But since I don't recall right now where that was from, it's also possible I changed or forgot something that's causing you the problem? Based on the error message you're indicating, I wonder if simply casting the argument to the "Contains" extension method would work? For example:
Although, if what you have now is working for you, probably no reason to mess with a good thing. In terms of which is more "performant", my guess is they are both incredibly similar.
Filter Child Nodes using Contains and Exclusion List
I would like to filter the Child nodes returned from a Where clause excluding all nodes that are in a list of excluded document types however I am still getting child nodes back regardless of the doctype being in the list of excluded doctypes.
See below example:
Can I achieve what I'm asking for in this way and I'm missing something or is it just not possiblle?
Thanks, Simon
I'm sure there may be a fancier way to pass in a filter statement (as a Func<INode,bool>) to the Descendants collection, but in the past, for simplicity, I have gotten away with the following:
Another trick I have used, when it's important for me to know for example the exact count of the nodes, is to use that same iteration logic but instead of "doing magic" where shown above, instead would build up a new List containing just the nodes I want. (And then, I can call .Count on this, iterate through it again as needed, etc.)
Good luck!
Thanks, I was trying to avoid doing that if I could because I am potentially grabbing more nodes in the request than what I really need. That said I should perhaps I should just take the plunge and allow a few extra lines to creep in just to get the job done as the overhead may be minimal anyway.
You raise a good point. It would be interesting to see "behind the scenes" profiling to see if there is any significant difference between passing in a filter clause to the Where method, ...or whether just looping the whole thing and deciding yourself. The only way really is for you to time it and see.
Another idea to consider is to use the XPath filtering method. This would also be something interesting to time, and see how it compares to the aforementioned approach. Something like:
Good luck! And let us know what you end up with!
If you can change your "node" to be a DynamicNode then you can use "proper" strongly-typed LINQ statements like this:
I am trying to use the code Funka posted but am getting an error.
The error I'm getting is
'string[]' has no applicable method named 'Contains' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax.
And my code
As far as I can see my code is the same as that posted. So why is it not working :(
I changed my approach and tried what Dan suggested. I made homeNode a DynamicNode and do this to select the children
Hi suzyb,
I'm glad you were able to get something working. Not sure why the sample you took from my post 7 weeks ago did not work, I'm fairly certain I had copied that from a working installation. But since I don't recall right now where that was from, it's also possible I changed or forgot something that's causing you the problem? Based on the error message you're indicating, I wonder if simply casting the argument to the "Contains" extension method would work? For example:
Although, if what you have now is working for you, probably no reason to mess with a good thing. In terms of which is more "performant", my guess is they are both incredibly similar.
Best of luck to you!
is working on a reply...