Jesper Tverskov, July 18, 2008

Replace XML with LINQ to XML in ASP.NET

In ASP.NET we have two main APIs for editing XML: W3C DOM and LINQ to XML. In this tutorial we look at how to replace elements and attributes in LINQ to XML. There are many more properties and methods and ways of achieving the same result than shown below. You must look up the proper documentation for all the details.

Editing XML basically consists of the following: adding, deleting or replacing elements and attributes, and updating content of elements and values of attributes. An API for editing also has properties and methods for comments, processing instructions, etc, but in this tutorial we only look at how to replace elements and attributes.

1. Replace element

I use the following XML document, products.xml, in many of my XML tutorials. How could we replace the product element having an attribute named "id" with a "p3" value? We want to replace the product element with "<test>abc</test>".

<?xml version="1.0" encoding="utf-8"?>
<products>
  <product id="p1">
    <name>Delta</name>
    <price>800</price>
    <stock>4</stock>
    <country>Denmark</country>
  </product>
  ...
  <product id="p3">
    <name>Alfa</name>
    <price>1200</price>
    <stock>19</stock>
    <country>Germany</country>
  </product>
  ...
</products>

To replace an element we first create an XDocument object and load the XML document, then we create an XElement for the old element and an XElement for the new element. We then replace the old element with the new directly.

To make it easy to find nodes in the XML document, I prefer to use XPath, "System.Xml.XPath", also when using LINQ to XML. Even when I could easily do without XPath, I prefer to use it for consistency.

2. LINQ to XML

2.1 replace-xml-linq.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="replace-xml-linq.aspx.cs" Inherits="replace_xml_linq" %>

2.2 replace-xml-linq.aspx.cs

using System;
using System.Xml.Linq;
using System.Xml.XPath;

public partial class replace_xml_linq : System.Web.UI.Page
{
  protected void Page_Load(object sender, EventArgs e)
  {
    XDocument xmldoc = XDocument.Load(Server.MapPath("products.xml"));
    XElement oldXElement = xmldoc.XPathSelectElement("products/product[@id = 'p3']");
    //note that we can make new element and content directly
    XElement newXElement = new XElement("test", "abc");

    //we also replace directly (in W3C DOM we need the parent element)
    oldXElement.ReplaceWith(newXElement);

    xmldoc.Save(Server.MapPath("products.xml"));
    Response.Redirect("products.xml"); // load file in browser
  }
}

LINQ to XML takes less code than W3C DOM but the nice thing about W3C DOM is that it is a standard API implemented by most programming languages. We can even read or edit an HTML document more or less the same using the HTML version of W3C DOM.

3. Replace attribute

Let us say that we only want to replace the "id" attribute with the "p3" value. We want to replace it with a new "test" attribute with the value "abc".

The easiest way is to create an XElement object for the parent of the attribute, remove the attribute and create a new attribute.

XDocument xmldoc = XDocument.Load(Server.MapPath("products.xml"));
XElement parentElement = xmldoc.XPathSelectElement("products/product[@id = 'p3']");//remove attribute we want to replace
parentElement.Attribute("id").Remove()

//create new attribute
parentElement.SetAttributeValue("test", "abc");

xmldoc.Save(Server.MapPath("products.xml"));

4. Replace XML in a namespace

See: Read XML with LINQ to XML for how to use XNamespace class.

Updated 2008-08-08