Thursday, August 30, 2012

Generic code to read XML document without knowing Root Node and Parent Node using LINQ

Recently i came across a situation where i was supposed to write code for reading a XML file where the structure of the document was fixed but following information was changing.

1) RootNode text,
2) ParentNode text
3) Number of Child nodes inside the parent node

So in Today's example we will see a way to write customized or generic code to read XML document where the Root Node, Parent Node and number of Child nodes can vary using LINQ.

Customers.xml
<?xml version="1.0" encoding="utf-8" ?>
<Customers>
  <Customer>
    <name>Aryan Mehta</name>
    <city>Bangalore</city>
    <country>India</country>
  </Customer>
  <Customer>
    <name>Steve Martin</name>
    <city>Sydney</city>
    <country>Australia</country>
  </Customer>
</Customers>


For this example i am using "Customer.xml" as the sample xml file.

//Loading the customers xml into the XDocument object
XDocument oXDocument = XDocument.Load(AppDomain.CurrentDomain.BaseDirectory + "Customers.xml");

//Retrieving the Root Node of the xml document dynamically
string RootNodeName = oXDocument.Root.Name.ToString();

//retrieving all the distinct elements inside a Root Node           
var ElementNodes = oXDocument.Root.DescendantNodes().OfType<XElement>().Select(x => x.Name).Distinct();

//ElementNodes.First will give the first node inside Root Node
//which is nothing but the Parent Node
var CustomerInfo = from CustomerInfoNode in oXDocument.Element(RootNodeName).Elements(ElementNodes.First())
                   select CustomerInfoNode;

//Looping through all the Customers elements in the CustomerInfo Element
foreach (XElement oXElement in CustomerInfo)
{
  //For separating the customer information
  Console.WriteLine("----Customer Information----");

 //Looping through Customer details of a particular Customer
 foreach (XElement oXElementData in oXElement.Elements())
 {
   //displaying the customer details in the console window
   Console.WriteLine(oXElementData.Name.ToString() + "="
                     oXElementData.Value.ToString());
 }
 Console.WriteLine("");
}
Console.ReadLine();

Output


When i use the same code for following "Employees.xml" which is with different Root Node and Parent Node.

Employees.xml
<?xml version="1.0" encoding="utf-8" ?>
<Employees>
  <Employee>
    <name>Aryan Mehta</name>
    <city>Bangalore</city>
  </ Employee >
  < Employee >
    <name>Steve Martin</name>
    <city>Sydney</city>
  </ Employee >
</ Employees >

Output

So the code of today's example can be used with different XML document having dynamic Root Node and Parent Node. But the only restriction is that the structure of the XML node should be same.

I hope this example has served the purpose of giving an idea on how to read a XML document in a generic way using LINQ.


Happy coding....


Sunday, August 26, 2012

Win 7 - Windows Service Installation Error - System.InvalidOperationException


I was getting the following error when i tried to install a simple WCF service as part of Windows Service in my machine which has WIN 7 as the operating system.

An exception occurred during the Install phase.
System.InvalidOperationException: Cannot open Service Control Manager on computer '.'. This operation might require other privileges.

The inner exception System.ComponentModel.Win32Exception was thrown with the following error message: Access is denied.

After lot of searching i found out there was one basic permission issue, When installing the Windows Service in a WIN 7 machine.

Solution:-

When using the InstallUtil command to install the service, we need to run the "Visual Studio Command Prompt(2010)" as an Administrator.


Then the Visual Studio Command Prompt window will open and you can write the InstallUtil command to install the Windows Service in your machine:-


This works fine for me. I didn't change any setting using the Registry.

Happy Coding..........

Saturday, August 11, 2012

Customizing the XML root node using Linq

Sometimes we come across a situation where the XML data, our application received from different sources needs to be having the Root node as expected by our application.

Obviously the restriction can be applied on other application for defining the XML as expected by the calling application. But is the datasource are dynamic then it can create some issues.

In today's example we will see a simple way to customize XML root node using the LINQ as per our requirement. 

For this example to work System.Xml.Linq namespace should be referenced.

Customer.xml

<?xml version="1.0" encoding="utf-8" ?>
<Customers>
  <Customer>
    <name>Aryan Mehta</name>
    <city>Bangalore</city>
    <country>India</country>
  </Customer>
  <Customer>
    <name>Steve Martin</name>
    <city>Sydney</city>
    <country>Australia</country>
  </Customer>
  <Customer>
    <name>Sandra Smith</name>
    <city>New York</city>
    <country>United States</country>
  </Customer>
</Customers>

//Loading the customers xml into the XElement object
XElement oXElement = XElement.Load(AppDomain.CurrentDomain.BaseDirectory + "Customers.xml");

//select all the elements using Linq 
var AllElements = from p in oXElement.Elements() select p;


//Defining oXElementReturn to hold the customized xml
XElement oXElementReturn = null;

//Adding customized root node to the return XElement
oXElementReturn = new XElement("CustomizedRootNode");

//Looping through all the elements in the xElement
foreach (XElement xElement1 in AllElements)
{
   //Creating a customized parent node inside root node
   XElement oXElementNode = new XElement("CustomizedParentNode");

   //Looping through all the elements inside parent node
   foreach (XElement xElement2 in xElement1.Descendants())
   {                   
     //Adding the node name and values to the parent node
     XElement oNewXElement = new 
               XElement(xElement2.Name.ToString());
     oNewXElement.Value = xElement2.Value;
     oXElementNode.Add(oNewXElement);
   }
   //Finally the parent node is added to the root node
   oXElementReturn.Add(oXElementNode);
}
//Once the customized return xElement is ready, the output can be displayed on console window
Console.WriteLine(oXElementReturn.ToString());

Output:- 


As it can be seen the xml document is customized as per my needs. I am not saying this is the perfect way but this is one of the way you can use to customize the Xml Root node and Parent Node.

And this can be extended to modify the Xml elements also as per your requirement.

I have used Console.Write for writing the output to demonstrate the output retrieved. You can use any way the data is required to be displayed or stored in a collection.


Happy Coding.........