Linq to XML – Adding,Updating and Deleting data

The previous post about Linq to XML introduced how to query XML data using LINQ. LINQ allows us to not only query XML in a truly unique way, but also create XML documents in a very expressive manner. This post will talk about other operations on the XML: adding, updating and deleting data.

First, lets create a sample XML document:

   1:  XElement book = new XElement("Books", new XElement("Book",
   2:      new XAttribute("publisher", "O'Reilly Media, Inc."),
   3:          new XAttribute("price", "40$"),
   4:          new XElement("title", "Learning WCF: A Hands-on Guide"),
   5:          new XElement("authors", new XElement("author", "Michele Bustamante"))));
   7:  book.Save("Books.xml");

Adding data to the XML document

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 other ways also…) and then add them to the document.

The following adds a new book:

   1:  XElement doc = XElement.Load("Books.xml");
   2:  XElement newBook = new XElement("Book",
   3:      new XAttribute("publisher", "Microsoft Press"),
   4:      new XAttribute("price", "45$"),
   5:      new XElement("title", "Introducing Microsoft LINQ"),
   6:      new XElement("authors", new XElement("author", "Paolo Pialorsi"), 
   7:          new XElement("author", "Marco Russo")));
   9:  doc.Add(newBook);
  10:  doc.Save("Books.xml");

We must save the xml with the save method, because in LINQ to XML, no changes are made to the loaded XML document until that document is saved.

The XML document now is:

   1:  <?xml version="1.0" encoding="utf-8"?>
   2:  <Books>
   3:    <Book publisher="O'Reilly Media, Inc." price="40$">
   4:      <title>Learning WCF: A Hands-on Guide</title>
   5:      <authors>
   6:        <author>Michele Bustamante</author>
   7:      </authors>
   8:    </Book>
   9:    <Book publisher="Microsoft Press" price="45$">
  10:      <title>Introducing Microsoft LINQ</title>
  11:      <authors>
  12:        <author>Paolo Pialorsi</author>
  13:        <author>Marco Russo</author>
  14:      </authors>
  15:    </Book>
  16:  </Books>

Updating data

Updating XML data is also very simple; Just pick the element/attribute you wish to update and then set its new value.

   1:  XElement doc = XElement.Load("Books.xml");
   3:  //obtain a single book
   4:  IEnumerable<XElement> singleBook = (from b in doc.Elements(
   5:                                        "Book")
   6:                                      where ((string)b.Element(
   7:                                      "title")).Equals("Introducing Microsoft LINQ")
   8:                                      select b);
  10:  //update book, should only be 1
  11:  foreach (XElement xe in singleBook)

12: {

  13:      xe.SetAttributeValue("price", "39$");
  15:      //use the ReplaceContent method to do the replacement for all attribures
  16:      //this will remove all other attributes and save only the price attribute
  17:      xe.ReplaceAttributes(new XAttribute("price", "32$"));
  18:  }
  20:  doc.Save("Books.xml");

Deleting data

We simply have to get the object we want to delete and then delete it using the Remove() method.

   1:  XElement doc = XElement.Load("Books.xml");
   3:  //obtain the first Book
   4:  IEnumerable<XElement> firstBook = (from b in doc.Elements(
   5:                                        "Book")
   6:                                        select b).Take(1);
   8:  //delete book price
   9:  foreach (XElement xe in firstBook)
  10:  {
  11:      xe.Attribute("price").Remove();
  12:  }
  14:  doc.Save("Books.xml");

Other way: we pass a lambda expression in as an argument to the Where extension method.

As you can see, Xlinq is really simple and great way to work with XML.


Query XML using XLINQ

LINQ to XML is a built-in LINQ data provider that is implemented within the System.Xml.Linq namespace in .NET 3.5.
It enables us do the following to XML data:

  • Read.
  • Construct.
  • Write.

We can perform LINQ queries over XML from the file-system, from a remote HTTP URL or web-service, or from any in-memory XML content.
LINQ to XML provides much richer (and easier) querying and data shaping support than the low-level XmlReader/XmlWriter API in .NET 2 and also much more efficient with usage of much less memory than the DOM API that XmlDocument provides. That’s because it does not require you to always have a document object to be able to work with XML. Therefore, you can work directly with nodes and modify them as content of the document without having to start from a root XmlDocument object. This is a very powerful and flexible feature that you can use to compose larger trees and XML documents from tree fragments. Now that you have an overview of the XLinq’s capabilities, the next few sections will examine the reading and writing features of XLinq before discussing the query capabilities.

01 (Figure and classes explanations are taken from XLINQ overview.doc)

Of the classes shown in this figure, the XNode and XContainer classes are abstract. The XNode class is the base for element nodes, and provides a Parent method and methods such as AddBeforeThis, AddAfterThis, and Remove for updates in the imperative style. For IO, it provides methods for reading (ReadFrom) and writing (WriteTo).
Although the XElement class is bottom-most in the class hierarchy, it is the fundamental class. As the name suggests, it represents an XML element and allows you to perform the following operations:

  • Create elements with a specified element name
  • Change the element’s contents
  • Add, change, or delete child elements
  • Add attributes to the element
  • Save the element as an XML fragment
  • Extract the contents in text form

This post will introduce hoe to query xml and it is the first of series of posts regards to XLINQ.

Lets get a sense of how LINQ to XML works!

Query xml from URL

   1:  public static void GetRssFeedFromURL()
   2:  {
   3:      string url = "";
   5:      // load the rss feeds into the XElement
   6:      XElement feeds = XElement.Load(url);
   9:      if (feeds.Element("channel") != null)
  10:      {
  11:          var query = from f in feeds.Element("channel").Elements("item").Take(10)
  12:                      select new { Title = f.Element("title").Value, Link = f.Element("link").Value };
  14:          foreach (var feed in query)
  15:          {
  16:              Console.WriteLine(String.Format("Feed title: {0}",feed.Title));
  17:              Console.WriteLine(String.Format("Link: {0}",feed.Link));
  18:          }
  19:      }
  20:  }

XLinq is an XML query language that inherits from the LINQ query foundation. You can use it to query XLinq objects such as XElement, XDocument, etc using LINQ query facilities.

We start by loading the XML into memory using the Load() method of the XElement class. (Line 6).

After loading the XML , the next step is to retrieve all items (Line 11) and now you can query and iterate the results as described in my previous posts.(Var keyword, Getting started with Linq).

Very simple! This example load an XML from URL. What if you want to query XML from the file system? Nothing changed beside the uri parameter to load into the XElement. (Line 6)

   1:  public static void GetRssFeedFromFile()
   2:  {
   3:      string path = @"C:WorkProjectsSamplesVS2008SamplesLinqToXMLMaor Davids Blog.xml";
   5:      // load the rss feeds into the XElement
   6:      XElement feeds = XElement.Load(path);
   9:      if (feeds.Element("channel") != null)
  10:      {
  11:          var query = from f in feeds.Element("channel").Elements("item").Take(10)
  12:                      select new { Title = f.Element("title").Value, Link = f.Element("link").Value };
  14:          foreach (var feed in query)
  15:          {
  16:              Console.WriteLine(String.Format("Feed title: {0}", feed.Title));
  17:              Console.WriteLine(String.Format("Link: {0}", feed.Link));
  18:          }
  19:      }
  20:  }


As you can see, all the code snippets presented above are fairly simple. Once the XML loaded into the LINQ to XML API, you can write queries over that tree. The query syntax is easier than XPath or XQuery.


%d bloggers like this: