Jesper Tverskov, August 4, 2008

Add 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 add 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 add elements and attributes.

1. Add element

I use the following XML document, products.xml, in many of my XML tutorials. How could we add a "test" element and make it a child of the "products" element.

<?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>

There are basically four ways of adding an element. Take the parent element and use AddFirst() or Add() to add the new child as first or last child. Or take the reference element and use AddBeforeSelf() or AddAfterSelf() to add the new child before or after the reference child.

It is nice that we in LINQ to XML can use the reference element directly, but it is confusing that we use AddFirst(), Add(), AddBeforeSelf(), AddAfterSelf() in LINQ to XML, and PrependChild(), AppendChild(), InsertBefore(), InsertAfter() in W3C DOM.

In the following we show all four methods in LINQ to XML, adding the same "test" element four times. 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 add-xml-linq.aspx

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

2.2 add-xml-linq.aspx.cs

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

public partial class add_xml_linq : System.Web.UI.Page
{
  protected void Page_Load(object sender, EventArgs e)
  {
    XDocument xmldoc = XDocument.Load(Server.MapPath("products.xml"));
    XElement parentXElement = xmldoc.XPathSelectElement("products");
    XElement refXElement = xmldoc.XPathSelectElement("products/product[@id = 'p3']");
    XElement newXElement = new XElement("test", "abc");

    // a) append element
    parentXElement.Add(newXElement);

    // b) prepend element
    parentXElement.AddFirst(newXElement);

    // c) insert before element
    refXElement.AddBeforeSelf(newXElement);

    // d) insert after element
    refXElement.AddAfterSelf(newXElement);

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

The W3C DOM API takes more code than LINQ to XML 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. Add attribute

Let us say that we want to add a "test" attribute to the product element already having an "id" attribute with a "p3" value. The order of attributes in an element is not important and attribute names in an element must be unique. We simply take the parent element and create the new attribute.

XDocument xmldoc = XDocument.Load(Server.MapPath("products.xml"));
XElement parentElement = xmldoc.XPathSelectElement("products/product[@id = 'p3']");

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

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

4. Add XML in a namespace

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

Updated 2008-08-05