by
Granville Barnett | 24 September 2007
In the
previous page, we started exploring how LINQ and XML
work with each other. In this page, let's continue by
learning how you can use LINQ to make other XML tasks
easier.
Updating XML data is also very simple, we just have to pick
the element/attribute we wish to update and then set its new
value. In this particular example we are just setting the
value of the publisher attribute; when dealing with elements
there are a host of methods we can use to do a similar
operation.
- XElement
books
= XElement.Load(@"Books.xml");
- books.Element("book").Attribute("publisher").Value
= "MS
Press";
- books.Save(@"Books.xml");
Imagine you wake up one morning and suddenly feel the urge
to get rid of all books of a particular publisher in your
book collection – we will now construct the relevant LINQ
query to do this:
- XElement
doc =
XElement.Load("Books.xml");
- doc.Descendants("book").Where(x
=>
string)x.Attribute("publisher")
== "MS
Press").Remove();
- doc.Save("Books.xml");
Here we pass a lambda expression in as an argument to the
Where extension method. This lambda expression takes one
argument (an XElement) and returns a Boolean depending on
whether or not the attribute publisher of the book element
is equal to MS Press.
Don’t be alarmed by the lambda expression argument to the
Where extension method for now – we will cover lambda
expressions later on in this article.
So far we have looked at hard-coded XML – a great feature of
LINQ to SQL is that we can actually generate an XML document
directly from a query. The process of creating an XML
document dynamically is very easy, and it’s something that I
have grown to really appreciate ever since picking up the
LINQ May 2006 CTP.
For our first example we will output the title of each
book in the database:
- BookShop
db =
new
BookShop(_conn);
- XElement
titles
= new
XElement("titles",
from
b in
db.GetBooks()
-
select new
XElement("title",
-
b.Title));
- Console.WriteLine(titles);
The code generates an XML document with the structure
shown in the following image:
[ the XML document you see when you print out titles ]
Here, instead of creating a new anonymous type like we
may do when selecting specific properties of an entity, we
create the appropriate XML types – constructing a perfect
XML document while using a very small amount of code. I
still get excited when I use this particular feature of LINQ
to SQL, look at how much code we are writing. The simplicity
of it is just great!
One of the concepts introduced in our last code snippet
was the ability to actually nest a query within the
definition of an XElement type. Our next example builds on
this concept and introduces a second nested query so that we
can loop through all the authors associated with any
particular book:
- XElement
books
= new
XElement("books",
from
b in
db.GetBooks()
-
select
new
XElement("book",
new
XAttribute("publisher",
-
b.PublisherName),
-
new XElement("title",
b.Title),
-
new XElement("authors",
-
from
a
in
db.GetAuthorByBookId(b.BookId)
-
select
new
XElement("author",
-
a.AuthorName))));
-
- Console.WriteLine(books);
The result of running the above code is shown below:
[ the results from running a nested query ]
Phew! As you can see, using LINQ with XML makes many
common tasks, if not more easy, more elegant. In the next
page, let's shift gears and talk a little about lambda
expressions.
Onwards to the
next page.
|