C# Как использовать Linq для коллекции XmlAttributeCollection в другом операторе Linq?

У меня есть элемент XML с подэлементами, например, так:

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

Я использую уже существующий метод MyMethod() чтобы получить Groups элемент, который возвращает XmlNodeList объект, который я бросил на XmlNode, После этого я хочу использовать оператор Linq для выборки только тех групп, которые имеют name атрибут в них и хранить эти имена в списке строк.

В приведенном ниже фрагменте кода я пытаюсь проверить, равно ли имя первого атрибута узла XML "name"но возможно, что "name" атрибут не всегда первый. Не могли бы вы помочь мне здесь и рассказать, как использовать другое утверждение Linq на Attributes свойство ниже? Attributes свойство имеет тип XmlAttributeCollection.

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

РЕДАКТИРОВАТЬ: мне удалось найти решение, используя встроенный метод GetNamedItem:

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

2 ответа

Ключевым методом для вашего вопроса является метод расширения .SelectMany которые возвращают уплощенную коллекцию из коллекции коллекций.

В качестве альтернативы вы можете использовать LINQ to XML (звучит как правильный инструмент для работы;))

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();

Что ты об этом думаешь:

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

Должно соответствовать вашей цели, чтобы получить объект с конкретным именем, полный код:

List<string> result = MyMethod().Cast<XmlNode>()
        .SelectMany(node => node.Attributes).Where(a => a.Name == "name")
        .Select(a=> a.Value).ToList();
Другие вопросы по тегам