Группировка элементов XElement (Linq) - PullRequest
4 голосов
/ 16 ноября 2011

У меня есть XElement, структурированный так:

<items>
    <item>
        <param1>A</param1>
        <param2>123</param2>
    </item>
    <item>
        <param1>B</param1>
        <param2>456</param2>
    </item>
    <item>
        <param1>A</param1>
        <param2>789</param2>
    </item>
    <item>
        <param1>B</param1>
        <param2>101112</param2>
    </item>
</items>

Я хочу получить словарь, в котором ключи привязаны к <param1> (A, B), а значением являются списки соответствующих элементов:

A -> <item><param1>A</param1><param2>123</param2></item>
     <item><param1>A</param1><param2>789</param2></item>
B -> <item><param1>B</param1><param2>456</param2></item>
     <item><param1>B</param1><param2>101112</param2></item>

Я пытался с этим:

var grouped = xItems.Descendants("item").GroupBy(r => r.Element("param1"))
    .ToDictionary(g => g.Key, g => g.ToList());

Но я все еще получаю 4 элемента, набор значений ключа с дублированными ключами, а не словарь из 2 элементов, как мне хотелось бы. Любая помощь?

Ответы [ 2 ]

3 голосов
/ 16 ноября 2011

Вы должны группировать по свойству .Value каждого элемента, а не самого элемента.Это потому, что элементы всегда будут разными, так как они на самом деле не являются одним и тем же элементом, даже если значения одинаковы.Таким образом, вы получите группу для каждого param1 элемента, независимо от их содержимого.

Попробуйте вместо этого:

using System;
using System.Linq;
using System.Xml.Linq;

class Program
{
    static void Main(string[] args)
    {
        const string docAsText = "...";
        var doc = XDocument.Parse(docAsText);
        var result = doc.Descendants("item")
            .GroupBy(r => r.Element("param1").Value) // Important: using .Value
            .ToDictionary(g => g.Key, g => g.ToList())
            ;

        foreach (var r in result)
        {
            Console.WriteLine(r.Key);
            Console.WriteLine(string.Join(",", r.Value));
        }
    }
}

Это напечатает:

A
<item>
  <param1>A</param1>
  <param2>123</param2>
</item>,<item>
  <param1>A</param1>
  <param2>789</param2>
</item>
B
<item>
  <param1>B</param1>
  <param2>456</param2>
</item>,<item>
  <param1>B</param1>
  <param2>101112</param2>
</item>
2 голосов
/ 16 ноября 2011

Хорошо, нашел это. Я забыл сгруппировать по VALUE элемента. Следующие работы:

var grouped = xItems.Descendants("item").GroupBy(r => r.Element("param1").Value)
    .ToDictionary(g => g.Key, g => g.ToList());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...