Access XML data using LINQ to XML

Hi Friends,

Today we would be learning the way to read complex XML data using LINQ to XML, which would include 2 examples:

1. Reading XML data without namespaces.
2. Reading XML data with namespaces.

In real life , we would be dealing with both of the above senarios very frequently. There are lot of approaches to read XML document, it could be XMLPathNavigator, XMLDocument etc-2. we would be taking the simplest approach to read XML document through LINQ.

Reading XML data without Namespaces

            Below is a complex xml document which contains nodes at n level,  we need to read this document  to fetch the City,Temperature and Image from it.

To go to Element at n level, we will use Element("X").Element("Y")... and to fetch attribute value of some element we will write Element("X").Attribute("Y").Value.
                XDocument doc = XDocument.Load(reader); //Creating the XDocument object and instantiating it with Xml file data.

                var lv1s = (from lv1 in doc.Descendants("weather") //Weather is a node under which we need to fetch descendants. 
                            select new
                            {
                                City = lv1.Element("forecast_information").Element("city").Attribute("data").Value,
                                TempC = lv1.Element("current_conditions").Element("temp_c").Attribute("data").Value,
                                ImageUrl = lv1.Element("current_conditions").Element("icon").Attribute("data").Value,
                            }).ToList();

                foreach (var v in lv1s)
                {
                    Consolte.WriteLine("{0} {1} {2}", v.City, v.TempC, v.ImageUrl);
                }
           

above code will work perfectly, if our xml doesn't have any kind of namespaces. But in many senarios we  will have to query xml which will have namespaces even.

 

Reading XML data with Namespaces

 

Below xml is having lot of namespaces in it. to access any node in the xml document with namespace, we need to prefix the node with namespace.

 

//creatinng variables for XmlNameSpace which we would be using to access different nodes.

                XNamespace y = "https://xml.weather.yahoo.com/ns/rss/1.0";
                XNamespace z = "https://www.w3.org/2003/01/geo/wgs84_pos#";
                XNamespace x = "https://where.yahooapis.com/v1/schema.rng";
                XNamespace p = "https://www.yahooapis.com/v1/base.rng";
                var lv1s = (from lv1 in doc.Descendants("query")
                            select new
                            {
                                City = lv1.Element("results").Element(x + "weather").Element(x+ "rss").Element(x + "channel").Element(x+"title").Value.Split('-')[1],
                                TempC = lv1.Element("results").Element(x + "weather").Element(x+ "rss").Element(x + "channel").Element(x+"item").Element(y+"condition").Attribute("temp").Value,
                                ImageUrl =  lv1.Element("results").Element(x + "weather").Element(x+ "rss").Element(x + "channel").Element(x+"item").Element(y+"condition").Attribute("code").Value + ".jpg",                                
                              }).ToList();

                foreach (var v in lv1s)
                {
                    Consolte.WriteLine("{0} {1} {2}", v.City, v.TempC, v.ImageUrl);
                }

 

So, these are the ways to access xml data with namespace and without namespace.

 

Happy Coding :-)