views:

180

answers:

1

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.

+3  A: 

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.)

Jon Skeet
Works like a charm, thank you. I knew it was supposed to be there, and in my mind it was (which apparently overrode what my eyes were seeing), sometimes it takes another person to point (and laugh) at the obvious :)
Alex K