OK, I didn't like the data format, so I changed it to this:
<root>
<Candidates>
<Sam_Kea/>
<Jeje/>
<John_Doe/>
</Candidates>
<Provinces>
<Province name='ProvinceA' Registered_Voters='115852'>
<Candidate name='Sam_Kea' votes='100'/>
<Candidate name='Jeje' votes='500'/>
<Candidate name='John_Doe' votes='400'/>
</Province>
<Province name='ProvinceB' Registered_Voters='25852'>
<Candidate name='Sam_Kea' votes='200'/>
<Candidate name='Jeje' votes='100'/>
<Candidate name='John_Doe' votes='300'/>
</Province>
<Province name='ProvinceC' Registered_Voters='317684'>
<Candidate name='Sam_Kea' votes='1000'/>
<Candidate name='Jeje' votes='1200'/>
<Candidate name='John_Doe' votes='190'/>
</Province>
</Provinces>
</root>
And this is the LINQ-to-XML code I used:
public void Run()
{
string fileToLoad = this.GetType().Name + ".xml";
XElement root = XElement.Load(fileToLoad);
// =======================================================
System.Console.WriteLine("\nCandidates:");
var allCandidates = from c in root.Element("Candidates").Elements()
select c.Name;
foreach (var d in allCandidates)
Console.WriteLine(" {0}", d.ToString());
// =======================================================
System.Console.WriteLine("\nNumber of Candidates in each Province:");
var s1 = from p in root.Element("Provinces").Elements()
select new
{
Prov = (string) p.Attribute("name"),
NumCandidates = p.Elements("Candidate").Count()
};
foreach (var d in s1)
Console.WriteLine(" {0}", d.ToString());
// =======================================================
System.Console.WriteLine("\nCandidate with most votes:");
var s2 = from p in root.Element("Provinces").Elements()
let maxVotes = (from c in p.Elements("Candidate") select c)
.Max(x => ((int)x.Attribute("votes")))
select new
{
Prov = (string) p.Attribute("name"),
Voters = (int) p.Attribute("Registered_Voters"),
Candidate = (from c in p.Elements("Candidate")
select c).Where(x => ((int)x.Attribute("votes")) == maxVotes)
.First().Attribute("name").Value
};
foreach (var d in s2)
Console.WriteLine(" {0}", d.ToString());
// =======================================================
System.Console.WriteLine("\nCandidates and the # of provinces won:");
var s4 = from can in allCandidates
let count = (from p in s2 where p.Candidate == can select p).Count()
orderby count descending
select new { Candidate = can, NumberOfProvincesWon = count };
foreach (var d in s4)
Console.WriteLine(" {0}", d.ToString());
}
Output:
Candidates:
Sam_Kea
Jeje
John_Doe
Number of Candidates in each Province:
{ Prov = ProvinceA, NumCandidates = 3 }
{ Prov = ProvinceB, NumCandidates = 3 }
{ Prov = ProvinceC, NumCandidates = 3 }
Candidate with most votes:
{ Prov = ProvinceA, Voters = 115852, Candidate = Jeje }
{ Prov = ProvinceB, Voters = 25852, Candidate = John_Doe }
{ Prov = ProvinceC, Voters = 317684, Candidate = Jeje }
Candidates and the # of provinces won:
{ Candidate = Jeje, NumberOfProvincesWon = 2 }
{ Candidate = John_Doe, NumberOfProvincesWon = 1 }
{ Candidate = Sam_Kea, NumberOfProvincesWon = 0 }