Taher
Taher

Reputation: 593

C# LINQ-to-XML Select Elements where a Child Element Attribute is Maxiumum

I have an XML sample like this:

  <prs>
    <pr number="1">
      <revisions>
        <revision revNum="0"></revision>
        <revision revNum="1"></revision>
        <revision revNum="2"></revision>
      </revisions>
    </pr>
    <pr number="2">
      <revisions>
        <revision revNum="0"></revision>
        <revision revNum="1"></revision>
      </revisions>
    </pr>
    <pr number="3">
      <revisions>
        <revision revNum="0"></revision>
      </revisions>
    </pr>
  </prs>

I wanted to select <revision> element from each <pr> element where the attribute @revNum of the child element <revision> is maximum.

So the returned list is something like that:

<revision revNum="2"></revision>  >> Child of pr with @number=1
<revision revNum="1"></revision>  >> Child of pr with @number=2
<revision revNum="0"></revision>  >> Child of pr with @number=3

So I tried this code:

        XDocument testDoc = XDocument.Load("sample.xml");

        IEnumerable<XElement> revQuery =
            from rev in (testDoc.Descendants("pr").Select(pr => pr)).Descendants("revision")
            where int.Parse(rev.Attribute("revNum").Value) ==
            rev.Parent.Elements("revision").Max(revNum => int.Parse(revNum .Attribute("revNum").Value))
            select rev;

The result is OK at least thats what the Unit Test says, but I am not sure if the query is written well or not.

Upvotes: 0

Views: 199

Answers (1)

jdweng
jdweng

Reputation: 34421

This is how I would do it

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            var results = doc.Descendants("pr").Select(x => new
            {
                number = (int)x.Attribute("number"),
                maxRevNum = x.Descendants("revision").Max(y => (int)y.Attribute("revNum"))
            }).ToList();
        }
    }
}

Upvotes: 1

Related Questions