Suppose I have the following XML file, essentially a random list of training courses consolidated from various sources:
<?xml version="1.0" encoding="utf-8"?>
<Courses>
<Course>
<Name>Big Data Advanced - Spark</Name>
<Track>Big Data</Track>
<Code>BD-102</Code>
</Course>
<Course>
<Name>Big Data Advanced - YARN</Name>
<Track>Big Data</Track>
<Code>BD-102</Code>
</Course>
<Course>
<Name>Big Data Basics</Name>
<Track>Big Data</Track>
<Code>BD-101</Code>
</Course>
<Course>
<Name>DI Administration</Name>
<Track>Data Integration</Track>
<Code>DI-103</Code>
</Course>
<Course>
<Name>DI Advanced</Name>
<Track>Data Integration</Track>
<Code>DI-102</Code>
</Course>
<Course>
<Name>DI Basics</Name>
<Track>Data Integration</Track>
<Code>DI-101</Code>
</Course>
</Courses>
I would like to group these courses by the value of their Track node, then sort by Code inside each track. The expected result is:
<?xml version="1.0" encoding="utf-8"?>
<Courses>
<Track name="Big Data">
<Course>
<Name>Big Data Basics</Name>
<Track>Big Data</Track>
<Code>BD-101</Code>
</Course>
<Course>
<Name>Big Data Advanced - Spark</Name>
<Track>Big Data</Track>
<Code>BD-102</Code>
</Course>
<Course>
<Name>Big Data Advanced - YARN</Name>
<Track>Big Data</Track>
<Code>BD-102</Code>
</Course>
</Track>
<Track name="Data Integration">
<Course>
<Name>DI Basics</Name>
<Track>Data Integration</Track>
<Code>DI-101</Code>
</Course>
<Course>
<Name>DI Advanced</Name>
<Track>Data Integration</Track>
<Code>DI-102</Code>
</Course>
<Course>
<Name>DI Administration</Name>
<Track>Data Integration</Track>
<Code>DI-103</Code>
</Course>
</Track>
</Courses>
I know how to achieve this result with XSLT transforms. However, I recently discovered the beauty of LINQ and would love to do the same with a single elegant query. I tried to consolidate an expression from the answers in How do I order a Group result, in Linq? and Group by in LINQ, but I do not understand fully the new
part. Most of the time I end up with incorrect syntax that gives wrong or no results at all.
For example:
// Sort by Course Code and group by Track
var doc = XDocument.Load("all-courses.xml");
var query = doc.Root.Elements("Course")
.GroupBy(c => c.Element("Track").Value)
.Select(o => new { Track = o.Key, Courses = o.OrderBy(c => c.Element("Code").Value).ToList() }).ToList();
What I am missing/doing wrong?