Section 5.4. LINQ to XML


5.4. LINQ to XML

From its beginnings, LINQ was designed to manipulate XML data as easily as it manipulates relational data. LINQ to XML represents a new API for XML-based development, equivalent in power to XPath and XQuery yet far simpler for most developers to use.

For example, let's assume the data source for our hospital scheduling application is an XML document stored in the file SchedulingDocs.xml. Here's the basic structure of the document:

 <?xml version="1.0" standalone="yes"?> <SchedulingDocs>   <Calls>      <Call>         <Initials>mbl</Initials>         <DateOfCall>2006-10-01T00:00:00-05:00</DateOfCall>      </Call>      .      .      .   </Calls>   <Doctors>      <Doctor>         <Initials>ay</Initials>         <GivenFirstName>Amy</GivenFirstName>         <FamilyLastName>Yang</FamilyLastName>         <PagerNumber>53300</PagerNumber>         <EmailAddress>ayang@uhospital.edu</EmailAddress>         <StreetAddress>1400 Ridge Ave.</StreetAddress>         <City>Evanston</City>      </Doctor>      .      .      .   </Doctors>   <Vacations>      <Vacation>         <Initials>jl</Initials>         <DateOfDayOff>2006-10-03T00:00:00-05:00</DateOfDayOff>      </Vacation>      .      .      .   </Vacations> </SchedulingDocs> 

Using LINQ, we load this document as follows:

 import System.Xml.XLinq;  // LINQ to XML XElement root, calls, doctors, vacations; root = XElement.Load("SchedulingDocs.xml"); calls     = root.Element("Calls"); doctors   = root.Element("Doctors"); vacations = root.Element("Vacations"); 

We now have access to the three main elements of the XML document: calls, doctors, and vacations. To select all the doctors, it's a simple query expression:

 var docs = from doc in doctors.Elements()            select doc; 

And to find just those doctors living in Chicago:

 var chicago = from doc in doctors.Elements()               where doc.Element("City").Value == "Chicago"               orderby doc.Element("Initials").Value               select doc; 

As you can see, querying XML documents with LINQ is conceptually the same as that of relational databases, DataSets, and other objects. The difference is that the structure of the XML document must be taken into account, e.g., in this case the document's hierarchical design and its use of elements over attributes.

An important aspect of LINQ is the ability to easily transform data into other formats. In the world of XML, transformation is commonplace given the need to create XML documents as well as translate from one schema to another. For example, suppose we need to produce a new XML document containing just the names of the doctors, with their initials as an attribute:

 <?xml version="1.0" standalone="yes"?> <Doctors>   <Doctor Initials="bb">Boswell, Bryan</Doctor>   <Doctor Initials="lg">Goldstein, Luther</Doctor>   .   .   . </Doctors> 

This document is easily produced by the following query, which simply projects new XElements:

 var docs = from doc in doctors.Elements()            orderby doc.Element("FamilyLastName").Value,                    doc.Element("GivenFirstName").Value            select new XElement("Doctor",                     new XAttribute("Initials", doc.Element("Initials").Value),                     doc.Element("FamilyLastName").Value +                     ", " +                     doc.Element("GivenFirstName").Value); XElement newroot = new XElement("Doctors", docs); 

The last statement creates the root element <Doctors>, using the query to generate the <Doctor> sub-elements.

Finally, here's a real-world example of translating a text-based IIS logfile into an XML document. This example comes from a series of posts to the MSDN LINQ Project General Forum, "Transforming a TXT file into XML with LINQ to XML," http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=574140&SiteID=1. The logfile contains 0 or more lines of the form:

 Time  IP-address  Method  URI  Status 

For example:

 #Software: Microsoft Internet Information Services 5.1 #Version: 1.0 #Date: 2006-06-23 12:37:18 #Fields: time c-ip cs-method cs-uri-stem sc-status 12:37:18 127.0.0.1 GET /cobrabca 404 12:37:25 127.0.0.1 GET /cobranca 401 . . . 

Here's the LINQ query to produce an XML document from such a log:

 var logIIS = new XElement("LogIIS",                from line in File.ReadAllLines("file.log")                where !line.StartsWith("#")                let items = line.Split(' ')                select new XElement("Entry",                  new XElement("Time", items[0]),                  new XElement("IP", items[1]),                  new XElement("Url", items[3]),                  new XElement("Status", items[4])                )              ); 

LINQ over a text file? The next section will discuss this, and other examples, in more detail.

NOTE

The general focus of this Short Cut precludes an in-depth treatment of LINQ to XML. For more details, we encourage you to read the forthcoming Part 3 of this Short Cut series (expected Q4 2006), which focuses exclusively on LINQ to XML. Watch for an announcement at http://oreilly.com



LINQ[c] The Future of Data Access in C# 3. 0
LINQ[c] The Future of Data Access in C# 3. 0
ISBN: N/A
EAN: N/A
Year: 2006
Pages: 25

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net