Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / XML

LINQtoXML

3.33/5 (9 votes)
26 Jan 2012CPOL6 min read 31.5K  
Introduction to XML Programming using LINQ in .NET

What does this Document Contain?

This document provides an overview of how LINQ can be used in creating and querying XML. This document provides the real time scenarios which we come across, while working with LINQ to XML, with pieces of code and easy to understand screenshots of output.

Who Can Read?

Everyone who is interested in exploring how to use LINQ in .NET, to play with XML.

How is this Useful to me?

This document does not discuss all the topics in depth, but will surely serve you as a quick start guide to work with LINQ to XML.

LINQ: Language Integrated Query is a Microsoft .NET Framework component that adds the native querying capabilities to .NET Languages.

What is LINQ to XML: In memory XML Programming interface that enables us to work with XML from within the .NET Framework programming languages.

Advantage of LINQ to XML: Integration with LINQ, which enables us to write queries on the in memory XML Document to retrieve collection of Elements and Attributes. These Linq queries are syntactically different from XPath but provide similar functionality.

Ease of using query results as parameters to XElement and XAttribute object constructors enabling an easy approach in creating XML Trees, which further enable easy transformation of the XML Trees from one shape to another.

Namespace which needs to be included in your code in order to work with LINQ to XML: System.Xml.Linq.

Starting from .NET 3.5, Creating XML in .NET is made easy with LINQ (Language Integrated Query). Some important syntax changes in creating a XML document are here under.

XML in Older versions of .NET XML Starting from .NET 3.5
XMLDocument XDocument
XMLElementXElement
XMLAttributeXAttribute
XMLNamespaceXNamespace
XMLNodeXNode

Creating a Simple XML

We are creating an XDocument (nothing but an XML) with Employee details like Name, Id and Designation.

C#
XDocument document = new XDocument(
                new XElement("Employees",
                    new XElement("Name", "Krishna"),
                    new XElement("ID", "12345"),
                    new XElement("Designation", "Engineer")));

As shown in the above piece of code, it is as simple as mentioning a KEY, VALUE pair just like new XElement("Name", "Krishna").

And the output is:

image001.jpg

Creating XML with Element Attributes

In most of the real time scenarios, we need to create XML with Element attributes. Here is the code to create an Employees XML with their designation as Element attribute.

C#
XDocument xDocument = new XDocument(
                new XElement("Employees",
                    new XElement("Employee", "Pavan",
                        new XAttribute("Designation", "Developer")),
                        new XElement("Employee", "sudhir",
                            new XAttribute("Designation", "Tester"))));

Output:

image002.jpg

Creating XML with Namespace

When creating an XDocument with namespace, you have to explicitly add the namespace to the child element also (new XElement(myNamespace + "Employee", "sudhir"), so that it will be inside the parent element namespace, as shown here.

C#
XNamespace myNamespace = "https://www.microsoft.com";
XDocument xDocument = new XDocument(
                new XElement(myNamespace + "Employees",
                    new XElement(myNamespace + "Employee", "Pavan",
                        new XAttribute("Designation", "Developer")),
                        new XElement(myNamespace + "Employee", "sudhir",
                            new XAttribute("Designation", "Tester"))));

And the output will be as shown below:

image003.jpg

If you do not mention the namespace keyword (here it is “myNamespace”) while adding child elements, the output will be as shown here under:

image004.jpg

As spotted with a Red circle, we will get an empty attribute in all the Child Elements. So we need to append namespace for each Child Element while creating the XDocument.

Working with Multiple Namespaces

Some scenarios expect us to have multiple namespaces in the XDocument we create. One namespace is for Parent Node and the other for all the Child Nodes. In such cases, we need to use two different XNamespace variables as shown below:

C#
XNamespace firstNamespace = "https://www.microsoft.com";
XNamespace secondNamespace = "https://www.microsoft.com/myBlogs";

XDocument myDocument = new XDocument(
                new XElement(firstNamespace + "Employees",
                    new XElement(firstNamespace + "Employee", "Senthil"),
                    new XElement(firstNamespace + "Employee", "Prabhu"),
                    new XElement(secondNamespace + "Employee", "Sampath"),
                    new XElement(secondNamespace + "Employee", "Kumar")));

Output:

image005.jpg

Prefixing the Namespace

If we see the above example, in the output it looks messy to have the namespace URL in each and every Child Element. In order to overcome this, we can include the second namespace also in the Parent Element and assign a keyword for it and then append this keyword while creating XElements.

C#
XDocument myDocument = new XDocument(
                new XElement(firstNamespace + "Employees",
                    new XAttribute(XNamespace.Xmlns +"secondNamespace",secondNamespace),
                    new XElement(firstNamespace + "Employee", "Senthil"),
                    new XElement(firstNamespace + "Employee", "Prabhu"),
                    new XElement(secondNamespace + "Employee", "Sampath"),
                    new XElement(secondNamespace + "Employee", "Kumar")));

Output:

image006.jpg

Saving the XML

We can save the created XDocument to any location, as XML document:

C#
XDocument xDoc = new XDocument(
                new XElement("Friends",
                    new XElement("Friend", "Senthil"),
                    new XElement("Friend", "Prabhu")));

            xDoc.Save(@"c:\myTest.xml"); 

When we go to the physical path and open the saved XML in browser, we can see as below:

image007.png

Loading the Saved XML

We can load the saved XML document and create XDocument using the below piece of code. Here I am loading the XML document and then binding the generated XDocument to a string variable.

C#
XDocument myDoc = XDocument.Load(@"c:\myTest.xml");
string check = myDoc.ToString();

When we check with the string variable in Text visualizer, it looks like below:

image008.png

Methods of XElement Class

Attribute, Attributes, Element, Elements, Descendants, Ancestors.

There are many methods and it’s a big list to mention here. We will see how to make use of some of the most commonly used methods like the ones mentioned above.

  • Element: Gives you the immediate Child Node
  • Elements: Gives the collection of Child Elements of this element or document as per the document order
  • Descendants: Gives you all the Child Nodes
  • Attributes: Returns a collection of Attributes of this Element
  • Attribute: Returns the XAttribute of this XElement that has the specified XName

Getting Elements with a Specific Name

C#
XDocument myDocument = new XDocument(
                new XElement("Employees",
                    new XAttribute(XNamespace.Xmlns +"secondNamespace",secondNamespace),
                    new XElement(firstNamespace + "Employee", "Senthil"),
                    new XElement(firstNamespace + "Employee", "Prabhu"),
                    new XElement(secondNamespace + "Employee", "Sampath"),
                    new XElement(secondNamespace + "Employee", "Kumar")));

            foreach (XElement myElement in myDocument.Descendants
            (firstNamespace + "Employee"))
            {
               String sOne += (string)myElement;
            }

foreach statement is used to loop through all the values returned for Element “Employee” and then these values are assigned to a string variable. Explicit conversion is required while assigning the Element value to a string variable. And the output is:

image009.jpg

In the same way, we can get the Element attribute values, using the below query:

C#
foreach (XElement myElement in xdoc.Descendants("Employee"))
{
    foreach (XAttribute xAtt in myElement.Attributes())
    {
        String sTwo = (string)xAtt;
    }
}

Parsing a string to XDocument

Consider a string which contains XML, as shown below:

image010.png
C#
string myString =
                @"<?xml version=""1.0"" encoding=""utf-8""?>
                <BankDetails>
                    <AccountHolder>Sai Krishna</AccountHolder>
                    <AccountNumber>12345678912</AccountNumber>
                    <AccountType>Savings</AccountType>
                </BankDetails>";

Now, call the Parse method in order to generate XDocument from the above string:

C#
XDocument myXDoc = XDocument.Parse(myString);

Output:

image011.jpg

Using Query operators on XDocument

Consider we need all the Director names who direct “Action” Type movie, from the below XDocument.

C#
XDocument xdoc = new XDocument(
               new XElement("Directors",
                   new XElement("Director", "James cameron",
                       new XAttribute("Type", "Sci-Fi")),
                       new XElement("Director", "Guy Ritchie",
                           new XAttribute("Type", "Action")),
                               new XElement("Director", "clientEastwood",
                                   new XAttribute("Type", "Action")),
                                   new XElement("Director", "ManiRatnam",
                                       new XAttribute("Type", "Sci-Fi"))));

The query which we need to write:

C#
var myDirectors = from xE in xdoc.Descendants("Director")
                              where xE.Attribute("Type").Value == "Action"
                              orderby xE.Value
                              select xE.Value;
            foreach (var Director in myDirectors)
            {
                Console.WriteLine(Director);
            }

Output:

We get “Client Eastwood” and “Guy Ritchie” as they are having attribute type as “Action”.

image012.png

Appending Elements to Already Existing XDocument

Consider there is an XDocument already created. We need to add couple of additional elements to the existing XDocument. Say, we need to add two more employees details to the already existing Employee XML tree. The code here shows you how to do that:

C#
XDocument myDoc = new XDocument(
               new XElement("SASTeam",
                   new XElement("Employee",
                   new XElement("Designer", "Naveen"),
                   new XElement("DBA", "Shankar")
                   )));

If we check this XDocument, we will get the below XML tree.

Image 13

Now, add two more employee details as shown here:

C#
myDoc.Root.Element("Employee").Add(
                new XElement("Developer", "Kaipa"),
                new XElement("Tester", "Kartheek"));

And the output is:

image013.png

You can see in the output, that two employee details “Kaipa” and “kartheek” added to the existing Employee Tree.

XDocument and String

Consider the XDocument mentioned in the previous section. We can convert this to an XML string by just calling the Tostring() method.

C#
string myString = myDoc.ToString();

And the result string value is:

C#
myString =
"<SASTeam>\r\n  <Employee>\r\n    <Designer>Naveen</Designer>\r\n    
<DBA>Shankar</DBA>\r\n    <Developer>Kaipa</Developer>\r\n    
<Tester>Kartheek</Tester>\r\n  </Employee>\r\n</SASTeam>"

I can see that this is not what we expect. In order to remove the special characters like “\r\n”, we need to do as below, while assigning the XDocument to string.

C#
string myString = myDoc.ToString(SaveOptions.DisableFormatting);

And the result string is as shown below:

C#
myString =
"<SASTeam><Employee><Designer>Naveen</Designer><DBA>Shankar</DBA>
<Developer>Kaipa</Developer><Tester>Kartheek</Tester></Employee></SASTeam>"

The default SaveOption will be None (SaveOptions.None). We need to switch between the options based on our requirement.

XDeclaration Issue

In the above section if we observe, there is no XDeclaration in the XDocument. We will create the same XDocument, but with XDeclaration this time:

C#
XDocument myDoc = new XDocument(
                new XDeclaration("1.0","utf-8","yes"),
                   new XElement("SASTeam",
                       new XElement("Employee",
                       new XElement("Designer", "Naveen"),
                       new XElement("DBA", "Shankar")
                   )));

Now if we check with the myString, we will get:

In the result string, we can see that XML Declaration is missing. To overcome this, we need to explicitly append the declaration string as shown here:

image014.png
C#
string myString = myDoc.Declaration.ToString() +
myDoc.ToString(SaveOptions.DisableFormatting);

And now the string value is:

image015.jpg

Summary

LINQ to XML is the new approach in constructing, writing, reading and querying XML data using the latest .NET framework language capabilities. This new API simplifies working with XML and provides a superior developer experience.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)