ServicesResourcesConferencesOur TeamWeblogsAboutContact
   

Subscriptions

Post Categories

News

My new books

My Blogroll

INETA UG Leaders

Affiliations

News

Archives

Christian Nagel's OneNotes

.NET Training, Consulting, Coaching & Development


LINQ Part 3 - Filtering and Sorting XML

LINQ Part 1 was about filtering and sorting object lists. LINQ Part 2 had the same result with information from the database. In part 3 I'm showing how to get the same information from XML data.

The XML data I'm using is similar to the data from the database from part 2:

<Racers>
  <Racer>
    <Name>Fernando Alonso</Name>
    <Car>Renault</Car>
    <Wins>9</Wins>
  </Racer>
  <Racer>
    <Name>Giancarlo Fisichella</Name>
    <Car>Renault</Car>
    <Wins>2</Wins>
  </Racer>
  <!-- ... -->

</Racers>

The requirement now is - as it was before - to filter the racers by selecting only the racers that have more than three wins, and sorting the result by the number of wins.

Doing this the "traditional" way, it is possible to filter the racers using an XPath expression: /Racers/Racer[Wins > 3]. However, this doesn't do a sort. The resulting list can be sorted by sorting the object list. Here I've chosen to filter and sort using XML features: XSLT. The select attribute specifies the XPath filter expression, and the resulting elements are sorted according to the xsl:sort element:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="
http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <Racers>
      <xsl:apply-templates select="/Racers/Racer[Wins > 3]">
        <xsl:sort select="Wins" data-type="number" order="descending"/>
      </xsl:apply-templates>

    </Racers>
  </xsl:template>
  <xsl:template match="Racer">
    <Racer>
      <Name>
        <xsl:value-of select="Name"/>
      </Name>
      <Wins>
        <xsl:value-of select="Wins"/>
      </Wins>
    </Racer>
  </xsl:template>
</xsl:stylesheet>

Using the XslCompiledTransform (.NET 2.0) class, the XML document is transformed written to a memory stream:

XslCompiledTransform transform = new XslCompiledTransform();
   transform.Load("Racers.xslt");

MemoryStream stream = new MemoryStream();
XmlTextWriter output = new XmlTextWriter(stream, Encoding.UTF8);
transform.Transform("Racers.xml", output);

The XML data in the memory stream is loaded inside the XmlDocument class, and here all racers are iterated with a foreach:

XmlDocument resultDoc = new XmlDocument();
stream.Seek(0, SeekOrigin.Begin);
resultDoc.Load(stream);

foreach (XmlNode racer in resultDoc.SelectNodes("Racers/Racer"))
{
    Console.WriteLine("{0} {1}", racer.ChildNodes[0].InnerText,
         racer.ChildNodes[1].InnerText);
}

Now to a new version: how can the same result be achived using XLINQ?

XElement is a new class that represents an XML element but also allows loading XML data with the static Load method. Now similar to accessing data from objects and the database, with the XLINQ query expression from where orderby select, data can be filtered and sorted. racers.Elements("Racer") accesses all Racer elements. r.Elements("Wins") accesses the Wins element that is a child of a Racer element. Because the Wins element is optional, a cast to a nullable int int? is performed.

var racers = XElement.Load("Racers.xml");

var winners = 
   from r in racers.Elements("Racer")
   where (int?)r.Element("Wins") > 3
   orderby (int?)r.Element("Wins") descending
   select (string)r.Element("Name") + " " + (string)r.Element("Wins");

foreach (string name in winners)
{
    Console.WriteLine(name);
}

Comparing how to filter and sort XLINQ with XSLT, XLINQ has the great advantage that it uses the same principles as accessing object lists (LINQ) and accessing data from the database (DLINQ). There's no need to learn a complete different syntax as XSLT.

Christian

posted on Friday, March 17, 2006 12:56 PM

# re: LINQ Part 3 - Filtering and Sorting XML @ Friday, March 17, 2006 3:26 PM

awesome series, thanks. seeing LINQ in action helps me understand and appreciate the new C# 2.0 features. btw... i think u mean XLINQ up there in your example, not XQuery :)
vinnie

# re: LINQ Part 3 - Filtering and Sorting XML @ Friday, March 17, 2006 5:19 PM

Vinnie, thanks for your comments :-)
Of course I meant XLINQ. Corrected.
Christian Nagel

# Link Listing - March 19, 2006 @ Monday, March 20, 2006 4:13 AM

CAB Best Practices
[Via: ]
How to detect VS.NET DesignMode in server
controls [Via: Rumen Stankov...
Christopher Steen

# re: LINQ Part 3 - Filtering and Sorting XML @ Thursday, March 30, 2006 9:54 AM

One of the things I've disliked about the preview of XLinq is the explicit casting that is constantly being done upon accessing XElement and the like.

I think it would be a good exercise to implement and demonstrate a typed XDocument that implements a schema. It shouldn't be difficult...

Keith J. Farmer

# re: LINQ Part 3 - Filtering and Sorting XML @ Thursday, March 30, 2006 4:52 PM

Keith, in a future entry of this series I will show typed XML. This is supported by VB9. I hope for C# 3.0, too.
Christian Nagel

# LINQ Part 4 - What's behind a query expression? @ Friday, March 31, 2006 12:24 AM

LINQ part 4 shows what's behind query and lambda expressions.
Christian Nagel's OneNotes

# Language-Integrated Query (LINQ) @ Saturday, April 08, 2006 7:17 PM

I ran across four very interesting links (no pun intended) related to&amp;nbsp;Language-Integrated Query&amp;nbsp;(LINQ)...
Michael Primeaux's Blog

# Language-Integrated Query (LINQ) @ Saturday, April 08, 2006 9:56 PM

I ran across four very interesting links (no pun intended) related to&amp;nbsp;Language-Integrated Query&amp;nbsp;(LINQ)...
Michael Primeaux's Blog

# Language-Integrated Query (LINQ) @ Sunday, April 09, 2006 3:34 AM

I ran across four very interesting links (no pun intended) related to&amp;nbsp;Language-Integrated Query&amp;nbsp;(LINQ)...
Michael Primeaux's Blog

# Language-Integrated Query (LINQ) @ Sunday, April 09, 2006 3:34 AM

I ran across four very interesting links (no pun intended) related to&amp;nbsp;Language-Integrated Query&amp;nbsp;(LINQ)...
Michael Primeaux's Blog

# More LINQ @ Monday, May 15, 2006 10:01 AM

Scott Guthrie has some great information on using LINQ with ASP.NET.
Christian Nagel's OneNotes

# re: LINQ Part 3 - Filtering and Sorting XML @ Tuesday, January 16, 2007 9:16 PM

since LINQ exposes the expression tree, it SHOULD be possible to actually write something to read this expression tree and output XSLT!

So you could write LINQ, and output equivalent XSLT.

Jay R. Wren


Powered by Community Server, by Telligent Systems