Transform XML to Objects by Grouping its Data

In my previous blog, I have explained how to group data present in a XML file and transform the output into a new XML file. In this blog I will transform the data into a custom Object. I will be using the same XML file Products that I used in my previous blog, here is the link for my previous blog: Grouping Data in XML File using LINQ-XML.
 
Now, I want to group the products data by category and store the results into following custom type:
  1. public class Product  
  2. {  
  3.     public int ProductId { getset; }  
  4.     public string ProductName { getset; }  
  5.     public decimal Price { getset; }  
  6.     public string Color { getset; }  
  7. }  
  8.   
  9. public class ProductsByCategoty  
  10. {  
  11.     public string Category { getset; }  
  12.     public List<Product> ProductsUnderEachCategory { getset; }  
  13. }  
As you can see, the class design is straight forward, since we are grouping the products by category. In the ProductsByCategory class we have a property Category and since each category may have multiple products, we have a second property that will be a List of Product classes.

Here is the LINQ query to do that.
 
1. Method Syntax:
  1. List<ProductsByCategoty> productsByCategotyMS = products.Root.Descendants("Product")  
  2.         .GroupBy(p => p.Element("Category").Value)  
  3.         .Select(p => new ProductsByCategoty  
  4.         {  
  5.             Category = p.Key,  
  6.             ProductsUnderEachCategory = (p.Select(x => new Product  
  7.             {  
  8.                 ProductId = Convert.ToInt32(x.Element("ID").Value),  
  9.                 ProductName = x.Element("Name").Value,  
  10.                 Price = Convert.ToDecimal(x.Element("Price").Value),  
  11.                 Color = x.Element("Color").Value  
  12.                 })).ToList()  
  13.             }).ToList();  
 2. Query Syntax:
  1. List<ProductsByCategoty> productsByCategotyQS = (from p in products.Root.Descendants("Product")  
  2.           group p by p.Element("Category").Value into g  
  3.           select new ProductsByCategoty  
  4.           {  
  5.               Category = g.Key,  
  6.               ProductsUnderEachCategory = (from x in g  
  7.               select new Product  
  8.               {  
  9.                   ProductId = Convert.ToInt32(x.Element("ID").Value),  
  10.                   ProductName = x.Element("Name").Value,  
  11.                   Price = Convert.ToDecimal(x.Element("Price").Value),  
  12.                   Color = x.Element("Color").Value  
  13.               }).ToList()  
  14.               }).ToList();  
Now, we can simply fetch the output using a nested foreach loop:
  1. foreach (var item in productsByCategotyQS)  
  2. {  
  3.     Console.WriteLine("Category: {0}", item.Category);  
  4.     foreach (var pro in item.ProductsUnderEachCategory)  
  5.     {  
  6.         Console.WriteLine("ProductId: {0}, Name: {1}, Price: {2}, Color: {3}",  
  7.         pro.ProductId, pro.ProductName, pro.Price, pro.Color);  
  8.     }  
  9.     Console.WriteLine("-------------------------------------------------------");  
  10.  }  
Please let me know in case of any issues. Happy Coding :)