In previous posts, we have explained, how to create XML file in C# or how to read XML file using jQuery but in this post, I am going to provide you console application example to read XML file using C# or you can say parse XML file in C# (XMLreader or Linq).
Table of Contents
Before we begin, we will be using sample XML(books.xml) file as below
<?xml version="1.0"?>
<catalog>
<book>
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<description>An in-depth look at creating applications
with XML.</description>
</book>
<book>
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
<genre>Fantasy</genre>
<price>5.95</price>
<description>A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.</description>
</book>
<book>
<author>Corets, Eva</author>
<title>Maeve Ascendant</title>
<genre>Fantasy</genre>
<price>5.95</price>
<description>After the collapse of a nanotechnology
society in England, the young survivors lay the
foundation for a new society.</description>
</book>
<book>
<author>Corets, Eva</author>
<title>Oberon's Legacy</title>
<genre>Fantasy</genre>
<price>5.95</price>
<description>In post-apocalypse England, the mysterious
agent known only as Oberon helps to create a new life
for the inhabitants of London. Sequel to Maeve
Ascendant.</description>
</book>
<book>
<author>Corets, Eva</author>
<title>The Sundered Grail</title>
<genre>Fantasy</genre>
<price>5.95</price>
<description>The two daughters of Maeve, half-sisters,
battle one another for control of England. Sequel to
Oberon's Legacy.</description>
</book>
</catalog>
If you want, you can download the above sample XML file from here: https://qawithexperts.com/book.xml
Let's create a new console application in Visual Studio, so navigate to "File"-> "New" -> "Project" -> Select "Visual C#" (Left pane) and "Console Application" (Right pane) -> Name it "ReadXMLInCsharp" and click "Ok"
Once Visual Studio has created the project, place the "book.xml" in root directory of your project.
Read XML using XMLDocument in C#
using System;
using System.Xml;
namespace ReadXMLInCsharp
{
class Program
{
static void Main(string[] args)
{
//create XMLDocument object
XmlDocument xmlDoc = new XmlDocument();
//returns url of main directory which contains "/bin/Debug"
var url=System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
//correction in path to point it in Root directory
var mainpath = url.Replace("\\bin\\Debug", "") + "\\books.xml";
//load xml file
xmlDoc.Load(mainpath);
//save all nodes in XMLnodelist
XmlNodeList nodeList = xmlDoc.DocumentElement.SelectNodes("/catalog/book");
//loop through each node and save it value in NodeStr
var NodeStr = "";
foreach (XmlNode node in nodeList)
{
NodeStr = NodeStr+"\nAuthor "+ node.SelectSingleNode("author").InnerText;
NodeStr = NodeStr + "\nTitle "+node.SelectSingleNode("title").InnerText;
NodeStr = NodeStr + "\nGenre " + node.SelectSingleNode("genre").InnerText;
NodeStr = NodeStr + "\nPrice " + node.SelectSingleNode("price").InnerText;
NodeStr = NodeStr + "\nDescription -" + node.SelectSingleNode("description").InnerText;
}
//print all Authors details
Console.WriteLine(NodeStr);
}
}
}
Output:
In the above code, we are using XMLDocument class to load the XML file and then using XMLNodeList, we are fetching all the nodes inside "/catalog/book".
Once we have all the XMLNodes, we loop through it using foreach and print the XML data.
We are selecting each node value using .SelectSingleNode("Node_Name").InnerText
and appending it in main string "NodeStr" and then printing it in the end.
Read XML using LINQ in C#
There is one more widely used approach to read XML file, which is using Linq. As Linq is used to fetch data from database also, and it make's things very easy for C# developer, we can also read XML using linq.
using System;
using System.Xml;
using System.Xml.Linq;
namespace ReadXMLInCsharp
{
class Program
{
static void Main(string[] args)
{
//returns url of main directory which contains "/bin/Debug"
var url=System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
//correction in path to point it in Root directory
var mainpath = url.Replace("\\bin\\Debug", "") + "\\books.xml";
var NodeStr = "";
//get all elements inside book
foreach (XElement level1Element in XElement.Load(mainpath).Elements("book"))
{
//print each element value
//you can also print XML attribute value, instead of .Element use .Attribute
NodeStr = NodeStr + "\nAuthor " + level1Element.Element("author").Value;
NodeStr = NodeStr + "\nTitle " + level1Element.Element("title").Value;
NodeStr = NodeStr + "\nGenre " + level1Element.Element("genre").Value;
NodeStr = NodeStr + "\nPrice " + level1Element.Element("price").Value;
NodeStr = NodeStr + "\nDescription -" + level1Element.Element("description").Value;
}
//print all Authors details
Console.WriteLine(NodeStr);
}
}
}
Output is same as above.
One of the benefit of using Linq is, it makes code short and easy to read.
You can also get attribute of the XML values using Linq, suppose XML is as shown below
<book>
<author name ="Corets, Eva"/>
</book
Then in the above code, instead of using "level1Element.Element("author").Value
", you need to use "level1Element.Attribute("author").Value
", which returns attribute value as "Corets, Eva".
Read XML using XMLReader
This is another approach, which can be used to read XML file, and search any data inside XML. Its is fast approach and consumes less memory.
using System;
using System.Xml;
namespace ReadXMLInCsharp
{
class Program
{
static void Main(string[] args)
{
//returns url of main directory which contains "/bin/Debug"
var url=System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
//correction in path to point it in Root directory
var mainpath = url.Replace("\\bin\\Debug", "") + "\\books.xml";
XmlReader xReader = XmlReader.Create(mainpath);
xReader.ReadToFollowing("book");
var NodeStr = "";
while (xReader.Read())
{
switch (xReader.NodeType)
{
case XmlNodeType.Element:
NodeStr = NodeStr+ "\nElement name:" + xReader.Name;
break;
case XmlNodeType.Text:
NodeStr = NodeStr + "\nElement value:"+ xReader.Value;
break;
case XmlNodeType.None:
//do nothing
break;
}
}
//print all Authors details
Console.WriteLine(NodeStr);
}
}
}
Output:
Above Output is truncated, but you can see from the above output, we are printing Attribute name and then it's value using XMLReader.
Basically XMLReder, read each XML Node and then based on it's type we are printing value.
If XML Node type = "Element", we are printing Element name, if XML Node type is value, we are printing it's value.
Search any data in XML using C#
Now, you have seen all the ways to read XML, what if we need selected node in XML.
Considering above "books.xml", what if we need to print all books title where author is "Corets, Eva".
In this case, I would like to read XML using Linq
Here is the C# query code for it using Linq
// Query all books which has author "Corets, Eva"
var query = from c in xml.Root.Descendants("book")
where c.Element("author").Value== "Corets, Eva"
select c.Element("title").Value;
Complete example
using System;
using System.Linq;
using System.Xml.Linq;
namespace ReadXMLInCsharp
{
class Program
{
static void Main(string[] args)
{
//returns url of main directory which contains "/bin/Debug"
var url=System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
//correction in path to point it in Root directory
var mainpath = url.Replace("\\bin\\Debug", "") + "\\books.xml";
// Loading from a file, you can also load from a stream
var xml = XDocument.Load(mainpath);
// Query all books which has author "Corets, Eva"
var query = from c in xml.Root.Descendants("book")
where c.Element("author").Value== "Corets, Eva"
select c.Element("title").Value;
//print all books title
foreach (string titleName in query)
{
Console.WriteLine("Book's title: {0}", titleName);
}
}
}
}
Output:
Book's title: Maeve Ascendant
Book's title: Oberon's Legacy
Book's title: The Sundered Grail
That's it, we got all books which has author name as "Corets, Eva".
Which method is fastest?
To test which of the above XML reader method is fastest, I created a new console with start/stop watch to check time in Miliseconds, here is the complete C# Console code
using System;
using System.Diagnostics;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
namespace ReadXMLInCsharp
{
class Program
{
static void Main(string[] args)
{
//returns url of main directory which contains "/bin/Debug"
var url=System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
//correction in path to point it in Root directory
var mainpath = url.Replace("\\bin\\Debug", "") + "\\books.xml";
var stopwatch = new Stopwatch();
stopwatch.Start();
//create XMLDocument object
XmlDocument xmlDoc = new XmlDocument();
//load xml file
xmlDoc.Load(mainpath);
//save all nodes in XMLnodelist
XmlNodeList nodeList = xmlDoc.DocumentElement.SelectNodes("/catalog/book");
//loop through each node and save it value in NodeStr
var NodeStr = "";
foreach (XmlNode node in nodeList)
{
NodeStr = NodeStr + "\nAuthor " + node.SelectSingleNode("author").InnerText;
NodeStr = NodeStr + "\nTitle " + node.SelectSingleNode("title").InnerText;
NodeStr = NodeStr + "\nGenre " + node.SelectSingleNode("genre").InnerText;
NodeStr = NodeStr + "\nPrice " + node.SelectSingleNode("price").InnerText;
NodeStr = NodeStr + "\nDescription -" + node.SelectSingleNode("description").InnerText;
}
//print all Authors details
Console.WriteLine(NodeStr);
stopwatch.Stop();
Console.WriteLine("Time elapsed using XmlDocument (ms)= " + stopwatch.ElapsedMilliseconds);
stopwatch.Reset();
stopwatch.Start();
NodeStr = "";
//linq method
//get all elements inside book
foreach (XElement level1Element in XElement.Load(mainpath).Elements("book"))
{
//print each element value
//you can also print XML attribute value, instead of .Element use .Attribute
NodeStr = NodeStr + "\nAuthor " + level1Element.Element("author").Value;
NodeStr = NodeStr + "\nTitle " + level1Element.Element("title").Value;
NodeStr = NodeStr + "\nGenre " + level1Element.Element("genre").Value;
NodeStr = NodeStr + "\nPrice " + level1Element.Element("price").Value;
NodeStr = NodeStr + "\nDescription -" + level1Element.Element("description").Value;
}
//print all Authors details
Console.WriteLine(NodeStr);
stopwatch.Stop();
Console.WriteLine("Time elapsed using linq(ms)= " + stopwatch.ElapsedMilliseconds);
stopwatch.Reset();
stopwatch.Start();
//method 3
//XMLReader
XmlReader xReader = XmlReader.Create(mainpath);
xReader.ReadToFollowing("book");
NodeStr = "";
while (xReader.Read())
{
switch (xReader.NodeType)
{
case XmlNodeType.Element:
NodeStr = NodeStr + "\nElement name:" + xReader.Name;
break;
case XmlNodeType.Text:
NodeStr = NodeStr + "\nElement value:" + xReader.Value;
break;
case XmlNodeType.None:
//do nothing
break;
}
}
//print all Authors details
Console.WriteLine(NodeStr);
stopwatch.Stop();
Console.WriteLine("Time elapsed using XMLReader (ms)= " + stopwatch.ElapsedMilliseconds);
stopwatch.Reset();
}
}
}
Output:
Author Gambardella, Matthew
Title XML Developer's Guide
Genre Computer
Price 44.95
Description -An in-depth look at creating applications
with XML.
Author Ralls, Kim
Title Midnight Rain
Genre Fantasy
Price 5.95
Description -A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.
Author Corets, Eva
Title Maeve Ascendant
Genre Fantasy
Price 5.95
Description -After the collapse of a nanotechnology
society in England, the young survivors lay the
foundation for a new society.
Author Corets, Eva
Title Oberon's Legacy
Genre Fantasy
Price 5.95
Description -In post-apocalypse England, the mysterious
agent known only as Oberon helps to create a new life
for the inhabitants of London. Sequel to Maeve
Ascendant.
Author Corets, Eva
Title The Sundered Grail
Genre Fantasy
Price 5.95
Description -The two daughters of Maeve, half-sisters,
battle one another for control of England. Sequel to
Oberon's Legacy.
Time elapsed using XmlDocument (ms)= 15
Author Gambardella, Matthew
Title XML Developer's Guide
Genre Computer
Price 44.95
Description -An in-depth look at creating applications
with XML.
Author Ralls, Kim
Title Midnight Rain
Genre Fantasy
Price 5.95
Description -A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.
Author Corets, Eva
Title Maeve Ascendant
Genre Fantasy
Price 5.95
Description -After the collapse of a nanotechnology
society in England, the young survivors lay the
foundation for a new society.
Author Corets, Eva
Title Oberon's Legacy
Genre Fantasy
Price 5.95
Description -In post-apocalypse England, the mysterious
agent known only as Oberon helps to create a new life
for the inhabitants of London. Sequel to Maeve
Ascendant.
Author Corets, Eva
Title The Sundered Grail
Genre Fantasy
Price 5.95
Description -The two daughters of Maeve, half-sisters,
battle one another for control of England. Sequel to
Oberon's Legacy.
Time elapsed using linq(ms)= 7
Element name:author
Element value:Gambardella, Matthew
Element name:title
Element value:XML Developer's Guide
Element name:genre
Element value:Computer
Element name:price
Element value:44.95
Element name:description
Element value:An in-depth look at creating applications
with XML.
Element name:book
Element name:author
Element value:Ralls, Kim
Element name:title
Element value:Midnight Rain
Element name:genre
Element value:Fantasy
Element name:price
Element value:5.95
Element name:description
Element value:A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.
Element name:book
Element name:author
Element value:Corets, Eva
Element name:title
Element value:Maeve Ascendant
Element name:genre
Element value:Fantasy
Element name:price
Element value:5.95
Element name:description
Element value:After the collapse of a nanotechnology
society in England, the young survivors lay the
foundation for a new society.
Element name:book
Element name:author
Element value:Corets, Eva
Element name:title
Element value:Oberon's Legacy
Element name:genre
Element value:Fantasy
Element name:price
Element value:5.95
Element name:description
Element value:In post-apocalypse England, the mysterious
agent known only as Oberon helps to create a new life
for the inhabitants of London. Sequel to Maeve
Ascendant.
Element name:book
Element name:author
Element value:Corets, Eva
Element name:title
Element value:The Sundered Grail
Element name:genre
Element value:Fantasy
Element name:price
Element value:5.95
Element name:description
Element value:The two daughters of Maeve, half-sisters,
battle one another for control of England. Sequel to
Oberon's Legacy.
Time elapsed using XMLReader (ms)= 12
Basically, Linq is fastest, here is time comparison output.
-- First Run
Time elapsed using XmlDocument (ms)= 15
Time elapsed using linq(ms)= 7
Time elapsed using XMLReader (ms)= 12
-- Second Run
Time elapsed using XmlDocument (ms)= 18
Time elapsed using linq(ms)= 3
Time elapsed using XMLReader (ms)= 15
That's it.
You may also like to read:
Implementing Payment Gateway in C# (ASP.NET Core MVC Razorpay Example)