by
Granville Barnett | 24 September 2007
In the
previous page, you learned how to use LINQ with SQL
stored procedures by looking at a few examples. In this
page, let's look at how LINQ works with XML.
I have mentioned that LINQ can be used against several data
stores, and so far we have only covered in-memory
collections and relational data with SQL Server 2005.
However, we can also use LINQ with XML data. Dubbed LINQ to
XML, LINQ allows us to not only query XML in a truly unique
way, but also create XML documents in a very expressive
manner. You can find the LINQ extensions for XML in the
System.Xml.Linq namespace.
Let’s dive in and create a sample XML document to
represent a book and its related data:
- XElement
book =
new
XElement("book",new
XAttribute("publisher",
"MS Press"),
new
XElement("title",
"CLR Via C#"),
-
new XElement("authors",
-
new XElement("author",
"Jeffrey Richter")));
-
- Console.WriteLine(book);
You can see the result produced by this code in the
following image:
[ your XML document recreated ]
One of the things about which I was skeptical at first
was the whacky indentation used when defining an XML
document using some of the new types like
XElement and
XAttribute. This indentation is not compulsory, however it
is remarkably clear to read when reviewing your code, so I
would encourage you to preserve this indentation, if only
for code clarity.
We will now take the opportunity to look at a few queries of
XML data. For all the queries we load an XML document which
contains several book elements, using the same definition as
outlined in above. Just like any query, the simplest is to
drag everything down; we will take the same approach and
select all the book elements from the XML document as shown
in this snippet:
- XElement
doc =
XElement.Load("Books.xml");
-
- IEnumerable<XElement>
query
= doc.Descendants("book");
-
- foreach
(XElement
book
in query)
{
- Console.WriteLine(book);
- }
I’m sure that you will agree with me that it is dead easy
to query XML using LINQ – let’s now take the opportunity to
look at a query that selects only the books of a certain
publisher. Before we actually look at some code we need to
come to terms with types in XML documents – there are none!
For this reason we are provided with casts for all major
value and reference types (int,
double,
float,
string, etc…).
For example, to select only “MS Press” books use:
- XElement
doc =
XElement.Load("Books.xml");
-
- IEnumerable<XElement>
query
= doc.Descendants("book").Where(x
=> (string)x.Attribute("publisher")
== "MS
Press");
-
- foreach
(XElement
book
in query)
{
- Console.WriteLine(book);
- }
The result of this query can be seen in the following
image:
[ the output produced by our query ]
Adding XML to the existing XML document is very
simple, we need only construct our XML using a mixture of
XElement, and
XAttribute types (there are many more you can
use other than these two!) and then add them to the
document. The following adds a new book:
- XElement
doc =
XElement.Load("Books.xml");
-
- XElement
myBook
= new
XElement("book",
new
XAttribute("publisher",
"Addison-Wesley"),
new
XElement("title",
"Exceptional C++ Style"),
new
XElement("authors",
new
XElement("author",
"Herb Sutter")));
-
- doc.Add(myBook);
- doc.Save("Books.xml");
As with LINQ to SQL, where we have to call the
SubmitChanges method of the DataContext to commit the
changes to the database, in LINQ to XML, no changes are made
to the loaded XML document until that document is saved.
Onwards to the
next page.
|