XElement element grouping (Linq)

I have an XElement structured as follows:

<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 get a dictionary in which the keys are attached to <param1> (A, B), and the value is lists of correlation elements:

 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 set of key values ​​with duplicate keys, and not a 2-element dictionary, as I would like. Any help?

+4
source share
2 answers

You should group the .Value property for each element, not for the element itself. This is because the elements will always be different, because they are not actually the same element, even if the values ​​are the same. Thus, you will get a group for each element param1 , 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 produces:

 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> 
+3
source

Ok, found it. I forgot to group by VALUE element. The following works:

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

Source: https://habr.com/ru/post/1381441/


All Articles