.NET Language Integrated Query for XML


Introduction

 

XLINQ is a redesigned Document Object Model (DOM) XML Programming API. XLinq uses the latest .NET Framework-based language.  From an XML perspective XLinq provides the query and transformation power of XQuery and XPath integrated into .NET Framework languages that implement the LINQ pattern (e.g., C#, VB, etc.). XLinq simplifies programming against XML. The XLinq is part of the Linq family which consists of

  • Linq  - query for objects
  • DLinq - query for relational databases
  • Xlinq  -  query for XML 

Using functional construction capabilities of Xlinq, we can create XML from scratch. The other normal features that Xlinq provides are loading XML from files or streams, save XML to files or streams and also you can create, remove, update and delete xml elements and attributes.

 

Linq Project

 

The following example shows a sample of an XML file which we will use in our XQuery to find out the features it supports.

 

<Employees>

      <Employee>

                  <firstname>Satheesh</firstname>

                  <department>Engineering</department>

                  <location>

                        <city>Bangalore</city>

                        <state>Karnataka</state>

                        <country>India</country>

                  </location>

                  <phone type="office">+91(80)87654321</phone>

                  <phone type="mobile">+919012345678</phone>

      </Employee>

      <Employee>

                  <firstname>Kumar </firstname>

                  <department>Engineering</department>

                  <location>

                              <city>Chennai </city>

                              <state>TamilNadu </state>

                              <country>India</country>

                  </location>

                  <phone type="office">+91(44)87654321</phone>

                  <phone type="mobile">+919412345678</phone>

      </Employee>

</Employees>

 

To create the above XML, the typical way is to create the xml document object first and then creating the elements and attributes. Using XLinq we don't need to create XMLdocument object. We can directly create the XML Element. XLinq supports a feature called functional construction to build the XML tree. The above XML sample would be constructed using Xlinq as defined in the steps below.

To create the above XML, the typical way is to create the xml document object first and then creating the elements and attributes. Using XLinq we don't need to create XMLdocument object. We can directly create the XML Element. XLinq supports a feature called functional construction to build the XML tree. The above XML sample would be constructed using Xlinq as defined in the steps below

  • Open VS 2005 (after installing the Linq CTP release)
  • Create new project and select the project type as LINQ Preview and choose the template as Linq Console application 
  • Write the code as given in the below figure(available in the file attached)



  • Execute the project and see the xml file "employees" created at the location mentioned. You could see the xml files with all details as given above.

In the above example we have not used the XML document object to create the xml tree. But in case of W3C DOM, the XML document object acts as the container for the XML tree. In DOM XML all nodes, elements and attributes must be created in the context of the xml document object. But using XLINQ we don't need to depend on the xml document object. We can directly create the elements using XElement class of Xlinq. It doesn't mean that XLinq is not supporting the document object. You can still create the XML Document if necessary in case of adding comments and processing instructions to the XML as given below.

XLinq Classes

Following are some of the major classes that Xlinq Provides

 

Class Name Description
XDocument This should be used only if necessary. This acts as a container to hold the xml tree. This can be used only if you want to add comments and high level processing instructions.  You can also save the document as xml file.
XElement Using this class, we can create elements, modify element contents (add, remove, modify child elements), Modify element attributes, save as xml file.
XAttribute This one is used to create the name/value pair within the element of the xml. This Attributes has similar features as Elements.
XName This represents a full XML name consisting of an XNamespace object and the local name
XComment Represents an xml comment. This is derived from the abstract class XNode
XDocumentType Represents an XML Document Type Definition (DTD). Drived from the XNode abstract class.
XProcesingInstruction Represents the processing instruction of the XML Document. This is to convey the instruction to the application that uses the XML document. Derived from XNode.
XTest Represents a text node. Derived from XNode.
XDeclaration Represents an XML declaration. Used to declare the xml version, encoding and other details.

Next we will see some of the XLinq features and the usage of it's classes .

Loading/Creating XML

XLinq provides multiple input sources like String, TextReader,  XmlReader and File for loading XML. Use Parse method of XElement to load XML string and use the Load method of the XElement to load an XML file.

// Loading XML file

XElement EmpfromFile = XElement.Load(@"c:\demo\Employees.xml");

// Loading XML from String

XElement EmpfromString = XElement.Parse(@"<xml string here>");

 

In the first picture above, the XElement class is used for creating the XML Tree and the code looks like this 

 

new XElement("firstname", "Satheesh"),

new XElement("department", "Engineering"),       

 

In the above code, I have assigned the string value "Satheesh" to the XML element "firstname". Instead of hard coding the values, we can replace that with a variable or a method so that the value can be passed at run time as given below. 

 

// Passing variable instead of string for the element

{

...

string firstname = "Satheesh";

string department = "Engineering";

...

new XElement("firstname", firstname),

new XElement("department", department),

...

}       


// Get Mobile Number of the employee by calling the method

// GetCurrentMobileNumber()

{

...     

new XElement("phone", GetCurrentMobileNumber(),

                           new XAttribute("type", "mobile"))

...

}

 

Let's see how to create the XML elements using LINQ query and objects.  In this case we have to create the objects. Let's assume that we have a class for having the project details in a department something like this

 

class Project

{

public string projectName;

public string projectDescription;

public string projectManager;

public int projectHours;

public string[] resourceNames;

}

 

Create objects from this project class and have couple of projects with an array of resource names who are all working in the project

 

var Projects = new[] {

new Project {

projectName = "XYZ",

      projectDescription = "XYZ R&D project for XLinq",

      projectManager = "Sat",

      projectHours = 160,

resourceNames = new[] { "Sat", "Kumar", "Martin", "Suresh" }

      },

 

new Project {

projectName = "ABC",

      projectDescription = "ABC R&D project for XLinq",

      projectManager = "Amir",

      projectHours = 120,

resourceNames = new[] { "Ahmed", "Sachin", "Amir", "Salman" }

      }

};  

 

Now we can create the XML file from the above project information objects using the XLinq query as 

 

XElement projects =

new XElement("Projects",

          from proj in Projects

                    select new XElement("Project",

                    new XElement("ProjectName", projectName),

                    from Res in proj.resourceNames

                    select new XElement("Resource", Res)

                    )

);

 

The output of the above query would be

 

<Projects>

<Project>

<ProjectName>XYZ</ProjectName>

<ProjectDescription>XYZ R&amp;D project for XLinq</ProjectDescription>    <ProjectManager>Sat</ProjectManager>    <ProjectHours>160</ProjectHours>    <Resource>Sat</Resource>

<Resource>Kumar</Resource>

<Resource>Martin</Resource>

<Resource>Suresh</Resource>

</Project>

<Project>

<ProjectName>ABC</ProjectName>

<ProjectDescription>ABC R&amp;D project for XLinq</ProjectDescription>    <ProjectManager>Amir</ProjectManager>    <ProjectHours>120</ProjectHours>    <Resource>Ahmed</Resource>

<Resource>Sachin</Resource>

<Resource>Amir</Resource>

<Resource>Salman</Resource>

</Project>

</Projects>

 

XLinq Methods

 

XLinq provides various methods to easily manipulate the XML Elements and its contents. We can insert, update, delete and copy the contents of XML content. For example you can add a new element to the Employees XML tree with the Add() method. This will be added as the last child. If you want to add the element at the beginning as a first child then you can use the method AddFirst(). You can use AddBeforThis() and AddAfterThis() methods to add the elements before or after any particular Element

 

// Adding a new element as last child

XElement employeeJoinDate = new XElement("EmployeeJoinDate", "31st Dec 2007");

Employees.Add(employeeJoinDate);

 

 

// Adding a new element after an existing element

XElement employeeLastName = new XElement("lastname","Lastname");

XElement firstName = Employees.Element("Employee").Element("firstname");

firstName.AddAfterThis(employeeLastName);

 

In the above example the employeeLastName element was created without any parent. It means that it does not belong to any tree or it's not the child of any other element. Before adding the new element after the firstName element as firstName.AddAfterThis, you can check the parent property of the employeeLastName object which will return null. This is because the element does not belong to the XML tree and does not come under any parent. It's just an element.

 

Console.WriteLine(employeeLastName.Parent.Value); 

 

Add this new element after the firstName element of Employee element. Now the parent of new element employeeLastName will be the same as the firstname element as it is added to the same parent of firstname element.

 

Updating and deleting elements from the XML is similar to adding element to the XML. For example, to remove the firstname element of the Employee element just call Remove() method on the firstname element as below 

 

Employees.Element("Employee").Element("firstname").Remove();

 

Updating the Element value is also similar to the Add and Remove methods. You can use ReplaceContent() and SetElement() methods to update the content of the element. 
 
Attributes

 

In the same way we added, deleted and updated the elements, we can also update, delete and add attributes. For example, if you want to update the attribute type of the first phone element  from "office" to "Work" then just use the SetAttribute() method of the Element as below.  

 

Employees.Element("Employee").Elements("phone").First().SetAttribute("type", "Work");

 

We can add a new attribute using the same functional construction method as we did for creating new element. Here we must use the XAttribute instead of XElement.

 

We can also remove an existing attribute using the method Remove().

 

Reading from and Writing to Database

 

Let's take the example of below XML which has details of couple of projects. These details are stored in SQL database and we will see how to get the details as XML and how to post the changes back to the database.

 

<Products>

<Product>

    <ProductID>1160</ProductID>

    <CategoryID>15</CategoryID>

    <ModelName>KEYBOARD</ModelName>

    <UnitCost>INR1500</UnitCost>

    <discountPercent>10</discountPercent>

</Product>

<Product>

    <ProductID>1165</ProductID>

    <CategoryID>15</CategoryID>

    <ModelName>Mouse</ModelName>

    <UnitCost>INR1200</UnitCost>

    <discountPercent>10</discountPercent>

</Product>

</Products>

This XML can be constructed easily by using the LINQ query against the Database. The Query looks something like this.

 

XElement Products =
          new XElement("Products",            
                    from c in <database>.ProductInfo
                    where c.CategoryID== "15"
                    select new XElement("
ProductID ", c. ProductID), 
                    new XElement("
ModelName ", c. ModelName),
                    new XElement("
UnitCost ",c. UnitCost)
                    new XElement("discountPercent ",c. discountPercent)
                )
        );

The <database> is the object for connecting to the database and table object. Let's say the XML file which we have created is modified and we have to post the changes back to SQL Server database. For example, the discountPercent of all products has to be updated. To achieve this, we can write a Linq query something like this

foreach (var prod in Products.Elements("Product")) {
          ProductInfo pro = <Database>.ProductInfo.
                    First(c => c.ProductID == (string)prod.Element("ProductID"));
   pro.discountPercent = (string)prod.Element("discountPercent");
}

<database>.SubmitChanges();

There are lots of other features which we can make use of for XML programming. This is just an introduction to the features that XLinq provides.


Similar Articles