Creating an XML Document Using LINQ to XML

If you played with the XML Document Object Model classes to create XML  documents from scratch, it will be easy for you to migrate to a brand new set of  classes which allows you to create XML elements in a much more natural and  easier way. These classes are located inside the Sytem.Linq.Xml namespace. The classic way of loading an XML document is  by using the XmlDocument class from the System.Xml namespace.

XmlDocument doc = XmlDocument.Load("myXmlFile.xml");

There is no difference if you are going to use the newer XDocument class.

XDocument doc = XDocument.Load("myXmlFile.xml");

So what makes this new classes have besides from having shorter names  compared to their older versions? The answer is functional construction.  With functional construction, you don’t need to declare the XML DOM elements one  by one. You can simply use the overloaded constructors of each X class to suit  your needs. This can be seen clearer by looking at an example.

By using the old System.Xml‘s XML DOM classes, the following code is used to create a  simple XML file.

//A new XML Document
XmlDocument doc = new XmlDocument();
            
//Xml Declaration
XmlDeclaration declaration = doc.CreateXmlDeclaration("1.0", "utf-8", "yes");
//Attach declaration to the document
doc.AppendChild(declaration);

//Create a comment
XmlComment comment = doc.CreateComment("This is a comment");
//Attach comment to the document
doc.AppendChild(comment);
            
//Create root element
XmlElement root = doc.CreateElement("Persons");
//Attach the root node to the document
doc.AppendChild(root);
            
//Create a Person child element
XmlElement person1 = doc.CreateElement("Person");
//Add an attribute name with value John Smith
person1.SetAttribute("name", "John Smith");
//Crate Age element 
XmlElement person1Age = doc.CreateElement("Age");
person1Age.InnerText = "30";
//Create Gender element
XmlElement person1Gender = doc.CreateElement("Gender");
person1Gender.InnerText = "Male";

//Attach Age and Gender element to the Person element
person1.AppendChild(person1Age);
person1.AppendChild(person1Gender);

//Attach Person child element to the root Persons element
doc.DocumentElement.AppendChild(person1);

//Create another Person child element
XmlElement person2 = doc.CreateElement("Person");
//Add attribute name with value Mike Folley
person2.SetAttribute("name", "Mike Folley");
//Crate Age element 
XmlElement person2Age = doc.CreateElement("Age");
person2Age.InnerText = "25";
//Create Gender element
XmlElement person2Gender = doc.CreateElement("Gender");
person2Gender.InnerText = "Male";

//Attach Age and Gender element to the Person element
person2.AppendChild(person2Age);
person2.AppendChild(person2Gender);

//Attach second Person child element to the root Persons element
doc.DocumentElement.AppendChild(person2);

//Save the constructed XML into an XML file
doc.Save(@"C:\sample1.xml");

Example 1 – Using XML DOM classes to create a file

The above code will produce the followingXML:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!--This is a comment-->
<Persons>
   <Person name="John Smith">
      <Age>30</Age>
      <Gender>Male</Gender>
   </Person>
   <Person name="Mike Folley">
      <Age>25</Age>
      <Gender>Male</Gender>
   </Person>
</Persons>

Now let’s take a look at using the new LINQ to XML classes to create the very  same XML markup.

XDocument doc = new XDocument(
    new XDeclaration("1.0", "utf-8", "yes"),
    new XComment("This is a comment"),
    new XElement("Persons",
        new XElement("Person", new XAttribute("name", "John Smith"),
            new XElement("Age", new XText("30")),
            new XElement("Gender", new XText("Male"))),
        new XElement("Person", new XAttribute("name", "Mike Folley"),
            new XElement("Age", new XText("25")),
            new XElement("Gender", new XText("Male")))));

doc.Save(@"C:\sample2.xml");

Example 2 – Using LINQ to XML classes to create an XML  document

As you can see, using the XML DOM classes to construct an XML document  requires you to declare each component and attach each element to their proper  parents one by one. Using the LINQ to XML classes, you can see the every part of  the XML document you will create is instantiated inside the constructor of every  class. These method of creating XML markup is called functional construction.  Each LINQ to XML class’ constructor accepts arguments that may serve as child  elements or values of the element it represents. For example, the  XElement has the following overload of its constructor:

XElement(XName name, params object[] content)

The first parameter accepts the name of the element. You can simply pass a  string as the name and it will automatically be converted to an XName instance. The second parameter is special  because it allows you to pass any number of different kinds of objects such as  an XTextXAttribute,  or an XElement that will be a child element of  that current XElement. Other LINQ to XML class  only accepts one argument such as XComment and XText which both accept a string argument that represents the text they will render.

The following table shows some of the LINQ to XML classes you can use  together what part of an XML document they represent.

                Class                 Description
                XDocument                 Represents an XML Document
                XDeclaration                 Represents an XML Declaration
                XElement                 Represents an XML Element
                XAttribute                 Represents an attribute of an XML Element
                XComment                 Represents an comment
                XText                 Represents the inner text of an XML element.

Figure 1 – LINQ to XML Classes

For example, if you want to create an element named Person with a name  attribute of value John Smith, here’s the code to do that.

var personElement = new XElement("Person", new XAttribute("name", "John Smith"));

If you want to add a child element for that person, simply add another  argument to the constructor of XElement.

var personElement = new XElement("Person", new XAttribute("name", "John Smith"), 
                        new XElement("Age", new XText("30")));

The child argument has a name of Age and the next argument to its constructor is its inner text represented by the XText class.  You can also see in Example 2 how every XElement argument was indented. This is  to make it look more like the way we indent XML elements. You can already see how the XML output will look like simply by looking at the code.

At the end of Example 2 is a call to the XDocument.Save method. This method allows you to save the constructed XML  which is currently in memory, into an external XML file. The method accepts a  string argument which represents the file path of the file. If the file does not exist, then it will be created. If the file is already there, it will be  overwritten. There are other overloads of this method, but for now, this version  is sufficient to save the constructed XML to a file.