Alex K
Alex K

Reputation: 11155

Linq to XML, only take elements that have a certain child element

I would like to ask a follow up question to an oldie (but goodie) Reading the list of References from csproj files (though I am not the author of that question).

In my parsing of the csproj files I need to select all Compile elements that have Link element as a child.

I first attempted to extend the answer to the linked question as follows:

IEnumerable<string> links = csprojFile
        Element(msbuild + "Project")
        .Elements(msbuild + "ItemGroup")
        .Elements(msbuild + "Compile")
        .Where(element => element.HasElements)
        .Attributes("Include")

Which is obviously insufficient since it picks all elements that have any type of children (so while picking the ones I want, it also picks extras). So then I tried:

IEnumerable<string> links = csprojFile
        .Element(msbuild + "Project")
        .Elements(msbuild + "ItemGroup")
        .Elements(msbuild + "Compile")
        .Where(element => element.HasElements && element.Descendants("Link").Any())
        .Attributes("Include")
        .Select(element => element.Value);

... which doesn't return anything. I'm a beginner in Linq in general and Linq2XML in particular, but to me that "Where" clause says: "where element has children and at least one of those children is named Link". Is that wrong?

Help is greatly appreciated.

Upvotes: 1

Views: 1075

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1499790

I suspect it's a namespace problem - you're not using the namespace for "Link". Try this:

IEnumerable<string> links = csprojFile
        .Element(msbuild + "Project")
        .Elements(msbuild + "ItemGroup")
        .Elements(msbuild + "Compile")
        .Where(element => element.Descendants(msbuild + "Link").Any())
        .Attributes("Include")
        .Select(attr => attr.Value);

(The HasElements isn't really necessary.)

Upvotes: 3

Related Questions