简体   繁体   中英

C# How to use Linq on an XmlAttributeCollection within another Linq statement?

I have an XML element with subelements like so:

<Groups>
    <Group1 name="first" value="1" />
    <Group2 value="2" name="second" />
    <Group3 value="3" />
</Groups>

I'm using an already existing method MyMethod() to fetch the Groups element which returns an XmlNodeList object which I cast to an XmlNode . After that I want to use a Linq statement to fetch only those groups which have a name attribute in them and store those names in a list of strings.

In the code snippet below I'm trying to check if the first attribute's name of an XML node equals "name" but it is possible that the "name" attribute isn't always the first one. Could you please help me out here and tell me how to use another Linq statement on Attributes property below? Attributes property is of type XmlAttributeCollection .

List<string> result = MyMethod().Cast<XmlNode>()
    .Where(node => node.Attributes[0].Name == "name")
    .Select(node => node.Attributes[0].Value).ToList();

EDIT: I managed to find a solution using the built in method GetNamedItem :

List<string> result = MyMethod().Cast<XmlNode>()
    .Where(node => node.Attributes?.GetNamedItem("name") != null)
    .Select(node => node.Attributes?.GetNamedItem("name").Value).ToList();

What do you think about that:

List<string> result = MyMethod().Cast<XmlNode>()
    .SelectMany(node => node.Attributes).Where(a => a.Name == "name");

Should match your goal to got the object with the specific name, the full code become:

List<string> result = MyMethod().Cast<XmlNode>()
        .SelectMany(node => node.Attributes).Where(a => a.Name == "name")
        .Select(a=> a.Value).ToList();

Key method for your question is extension method .SelectMany which return flattened collection from collection of collections.

As alternative you can use LINQ to XML (sounds like right tool for the job ;))

var document = XDocument.Load("pathToXmlFile");

// Here you can use more complex logic of "MyMehthod" 
var allGroups = document.Descendants("Groups");

var names = allGroups.SelectMany(groups => groups.Elements())
                     .Where(group => group.Attribute("name"))
                     .Where(attribute => attribute != null)
                     .Select(attribute => attribute.Value)
                     .ToList();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM