LINQ to XML techniques: adding a namespace

In this post we built a very simple XML document using LINQ to XML. We saw the 3 most frequently used objects in the System.Xml.Linq namespace: XDocument, XElement and XAttribute. These objects and their constructors allow the creation of XML documents in a more fluent fashion than it was possible with the original XML related objects in the System.Xml namespace.

In this post we’ll see how to add a namespace to an XML document.

What is an XML namespace?

A namespace in XML is not much different from the namespaces in the world of programming. Each object we create in C#, Java, Python etc. will have a fully qualified name which starts with the namespace. A Customer object is not really called just Customer but something like MyCompany.Domains.Core.Customer. XML elements also have a namespace but that namespace can be an empty string. The document we created in the post referenced above had no namespaces at all. Therefore the fully qualified name of a “Band” node was an empty string, i.e. the namespace, followed by the node name Band: “” + “Band”. If you want to know all the details about XML namespaces you can consult this page.

One way to add a namespace to the document is through the XNamespace object which can simply be instantiated with a string literal. The namespace should be applied to every element whose node name belongs to that namespace. Here comes an example:

XNamespace xNamespace = @"http:\\www.mycompany.com\domains\music\";
XDocument bandsDocument = new XDocument(
	new XElement(xNamespace + "Bands",
		new XElement(xNamespace + "Band",
			new XAttribute("genre", "rock"),
			new XElement(xNamespace + "Name", "Queen"),
			new XElement(xNamespace + "NumberOfMembers", 4)),
		new XElement(xNamespace + "Band",
			new XAttribute("genre", "progressive"),
			new XElement(xNamespace + "Name", "Genesis"),
			new XElement(xNamespace + "NumberOfMembers", 5)),
		new XElement(xNamespace + "Band",
			new XAttribute("genre", "metal"),
			new XElement(xNamespace + "Name", "Metallica"),
			new XElement(xNamespace + "NumberOfMembers", 4))));

…which produces the following result:

<Bands xmlns="http:\\www.mycompany.com\domains\music\">
  <Band genre="rock">
    <Name>Queen</Name>
    <NumberOfMembers>4</NumberOfMembers>
  </Band>
  <Band genre="progressive">
    <Name>Genesis</Name>
    <NumberOfMembers>5</NumberOfMembers>
  </Band>
  <Band genre="metal">
    <Name>Metallica</Name>
    <NumberOfMembers>4</NumberOfMembers>
  </Band>
</Bands>

By applying the namespace to each and every node the output will have a single xmlns attribute in the root element. The namespace will apply for every node. If I, however, forget to specify the namespace on a node, e.g. on the second Band node then the resulting XML document will look weird:

<Bands xmlns="http:\\www.mycompany.com\domains\music\">
  <Band genre="rock">
    <Name>Queen</Name>
    <NumberOfMembers>4</NumberOfMembers>
  </Band>
  <Band genre="progressive" xmlns="">
    <Name xmlns="http:\\www.mycompany.com\domains\music\">Genesis</Name>
    <NumberOfMembers xmlns="http:\\www.mycompany.com\domains\music\">5</NumberOfMembers>
  </Band>
  <Band genre="metal">
    <Name>Metallica</Name>
    <NumberOfMembers>4</NumberOfMembers>
  </Band>
</Bands>

The child nodes of the second Band node received the same xmlns attribute. Therefore by applying the namespace on every node the namespace can be “factored out” to the root element.

We can also modify the node prefixes using namespaces and attributes. Note the extra XAttribute object after the root Bands node:

XNamespace xNamespace = @"http:\\www.mycompany.com\domains\music\";
XDocument bandsDocument = new XDocument(
	new XElement(xNamespace + "Bands",
		new XAttribute(XNamespace.Xmlns + "domain", xNamespace),
		new XElement(xNamespace + "Band",
			new XAttribute("genre", "rock"),
			new XElement(xNamespace + "Name", "Queen"),
			new XElement(xNamespace + "NumberOfMembers", 4)),
		new XElement(xNamespace + "Band",
			new XAttribute("genre", "progressive"),
			new XElement(xNamespace + "Name", "Genesis"),
			new XElement(xNamespace + "NumberOfMembers", 5)),
		new XElement(xNamespace + "Band",
			new XAttribute("genre", "metal"),
			new XElement(xNamespace + "Name", "Metallica"),
			new XElement(xNamespace + "NumberOfMembers", 4))));

Here’s the resulting document with prefixes modified to “domain”:

<domain:Bands xmlns:domain="http:\\www.mycompany.com\domains\music\">
  <domain:Band genre="rock">
    <domain:Name>Queen</domain:Name>
    <domain:NumberOfMembers>4</domain:NumberOfMembers>
  </domain:Band>
  <domain:Band genre="progressive">
    <domain:Name>Genesis</domain:Name>
    <domain:NumberOfMembers>5</domain:NumberOfMembers>
  </domain:Band>
  <domain:Band genre="metal">
    <domain:Name>Metallica</domain:Name>
    <domain:NumberOfMembers>4</domain:NumberOfMembers>
  </domain:Band>
</domain:Bands>

You can view all LINQ-related posts on this blog here.

Advertisement

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

One Response to LINQ to XML techniques: adding a namespace

  1. Ronan says:

    Great article . I was looking for this answer. Very helpful

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

Bite-size insight on Cyber Security for the not too technical.

%d bloggers like this: