Reputation: 58873
I have an XElement structured like this:
<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>
I want to obtain a dictionary where the keys are bound to <param1>
(A, B) and the value are lists of correlate items:
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>
I tried with this:
var grouped = xItems.Descendants("item").GroupBy(r => r.Element("param1"))
.ToDictionary(g => g.Key, g => g.ToList());
But I still get 4 elements, a key-value collection with duplicated keys, and not a 2 element dictionary as I'd like. Any help?
Upvotes: 4
Views: 925
Reputation: 59111
You should group by the .Value
property of each element rather than the element itself. This is because the elements will always be different, as they aren't actually the same element, even if the values are the same. So you'll get a group for every param1
element, regardless of their contents.
Try this instead:
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));
}
}
}
This prints out:
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>
Upvotes: 3
Reputation: 58873
Ok, found it. I forgot to group by the VALUE of the element. The following works:
var grouped = xItems.Descendants("item").GroupBy(r => r.Element("param1").Value)
.ToDictionary(g => g.Key, g => g.ToList());
Upvotes: 2