456

How do I read and parse an XML file in C#?

GEOCHET
  • 21,119
  • 15
  • 74
  • 98
Gajendra
  • 4,649
  • 2
  • 17
  • 3

12 Answers12

601

XmlDocument to read an XML from string or from file.

using System.Xml;

XmlDocument doc = new XmlDocument();
doc.Load("c:\\temp.xml");

or

doc.LoadXml("<xml>something</xml>");

then find a node below it ie like this

XmlNode node = doc.DocumentElement.SelectSingleNode("/book/title");

or

foreach(XmlNode node in doc.DocumentElement.ChildNodes){
   string text = node.InnerText; //or loop through its children as well
}

then read the text inside that node like this

string text = node.InnerText;

or read an attribute

string attr = node.Attributes["theattributename"]?.InnerText

Always check for null on Attributes["something"] since it will be null if the attribute does not exist.

George D Girton
  • 763
  • 10
  • 15
Wolf5
  • 16,600
  • 12
  • 59
  • 58
  • 1
    Valid, but Linq to XML is much nicer. – Finglas Jan 21 '10 at 16:27
  • 4
    Although you say it's 'nicer' is there any other disadvantage to doing it this way over LINQ? Personally I found this method to be the most simple, at least for my needs. – Kolors Jan 22 '13 at 19:34
  • 6
    I wrote this before I had begun using LINQ. LINQ is nice and can have easier readability. I mostly use LINQ myself these days. But some components do need the old style XML objects, so it still gets used now and then. I would recommend trying both the "old style" here and LINQ and see what fits you. – Wolf5 Jan 23 '13 at 09:36
  • 1
    Shouldn't the `XmlNode node = XmlDocument.Docu...` line really be `XmlNode = doc.Docu...`? Why was the answer changed and the `doc.` removed? – kodybrown Nov 03 '14 at 19:57
  • True. I have no idea why I changed that... Will fix. – Wolf5 Nov 04 '14 at 12:29
  • that what i need, simple and useful for me from VB.NET dev. – nghiavt Apr 27 '15 at 13:24
  • 1
    @Finglas in your opinion. :-) – Karlth Oct 29 '15 at 17:38
  • Linq may also not be available, if you're dealing with a legacy project. – user2366842 Mar 13 '19 at 01:51
  • its work for me, but the last exmaple i need write code like this: `node["theattributename"].InnerText` – izik f Mar 26 '19 at 15:13
  • 1
    `XmlDocument` is in `System.Xml`. – 4LegsDrivenCat Apr 12 '20 at 16:31
  • linq to xml is fastest as per what I see explained here https://qawithexperts.com/article/c-sharp/open-and-read-xml-in-c-examples-using-linq-xmlreader-xmldocu/310 – Jyoti May 03 '22 at 14:26
253

LINQ to XML Example:

// Loading from a file, you can also load from a stream
var xml = XDocument.Load(@"C:\contacts.xml");


// Query the data and write out a subset of contacts
var query = from c in xml.Root.Descendants("contact")
            where (int)c.Attribute("id") < 4
            select c.Element("firstName").Value + " " +
                   c.Element("lastName").Value;


foreach (string name in query)
{
    Console.WriteLine("Contact's Full Name: {0}", name);
}

Reference: LINQ to XML at MSDN

LW001
  • 2,452
  • 6
  • 27
  • 36
Konstantin Tarkus
  • 37,618
  • 14
  • 135
  • 121
22

Here's an application I wrote for reading xml sitemaps:

using System;
using System.Collections.Generic;
using System.Windows.Forms; 
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Data;
using System.Xml;

namespace SiteMapReader
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Please Enter the Location of the file");

            // get the location we want to get the sitemaps from 
            string dirLoc = Console.ReadLine();

            // get all the sitemaps 
            string[] sitemaps = Directory.GetFiles(dirLoc);
            StreamWriter sw = new StreamWriter(Application.StartupPath + @"\locs.txt", true);

            // loop through each file 
            foreach (string sitemap in sitemaps)
            {
                try
                {
                    // new xdoc instance 
                    XmlDocument xDoc = new XmlDocument();

                    //load up the xml from the location 
                    xDoc.Load(sitemap);

                    // cycle through each child noed 
                    foreach (XmlNode node in xDoc.DocumentElement.ChildNodes)
                    {
                        // first node is the url ... have to go to nexted loc node 
                        foreach (XmlNode locNode in node)
                        {
                            // thereare a couple child nodes here so only take data from node named loc 
                            if (locNode.Name == "loc")
                            {
                                // get the content of the loc node 
                                string loc = locNode.InnerText;

                                // write it to the console so you can see its working 
                                Console.WriteLine(loc + Environment.NewLine);

                                // write it to the file 
                                sw.Write(loc + Environment.NewLine);
                            }
                        }
                    }
                }
                catch { }
            }
            Console.WriteLine("All Done :-)"); 
            Console.ReadLine(); 
        }

        static void readSitemap()
        {
        }
    }
}

Code on Paste Bin http://pastebin.com/yK7cSNeY

Grant Winney
  • 65,241
  • 13
  • 115
  • 165
ajzeffer
  • 840
  • 1
  • 7
  • 13
17

There are lots of way, some:

  • XmlSerializer. use a class with the target schema you want to read - use XmlSerializer to get the data in an Xml loaded into an instance of the class.
  • Linq 2 xml
  • XmlTextReader.
  • XmlDocument
  • XPathDocument (read-only access)
Dirk Vollmar
  • 172,527
  • 53
  • 255
  • 316
eglasius
  • 35,831
  • 5
  • 65
  • 110
12

You could use a DataSet to read XML strings.

var xmlString = File.ReadAllText(FILE_PATH);
var stringReader = new StringReader(xmlString);
var dsSet = new DataSet();
dsSet.ReadXml(stringReader);

Posting this for the sake of information.

  • very fine! it s the quickest way i found to share information from sql xml columns and .net !! – elle0087 Jan 18 '18 at 14:30
  • Not ideal when you have multiple levels as it appears to put each level into its own table within the dataset. – Lenny K Mar 01 '19 at 17:00
  • It's still fine for that even. I guess it really depends on what your data actually looks like and how many layers deep the data is that you're after. – user2366842 Mar 13 '19 at 01:21
8

You can either:

Examples are on the msdn pages provided

Grzenio
  • 35,875
  • 47
  • 158
  • 240
6

Linq to XML.

Also, VB.NET has much better xml parsing support via the compiler than C#. If you have the option and the desire, check it out.

  • "All wrong"? Not accurate, I should think, unless that statement was in jest. The OP has provided no info. about the .NET version he works on. – Cerebrus Mar 13 '09 at 12:02
  • 2
    Heh, yeah. It was in jest, but I'm not funny, so I removed it. –  Mar 15 '09 at 16:48
2

Check out XmlTextReader class for instance.

Quintin Balsdon
  • 5,484
  • 10
  • 54
  • 95
Frederik Gheysels
  • 56,135
  • 11
  • 101
  • 154
1
public void ReadXmlFile()
{
    string path = HttpContext.Current.Server.MapPath("~/App_Data"); // Finds the location of App_Data on server.
    XmlTextReader reader = new XmlTextReader(System.IO.Path.Combine(path, "XMLFile7.xml")); //Combines the location of App_Data and the file name
    while (reader.Read())
    {
        switch (reader.NodeType)
        {
            case XmlNodeType.Element:
                break;
            case XmlNodeType.Text:
                columnNames.Add(reader.Value);
                break;
            case XmlNodeType.EndElement:
                break;
        }
    }
}

You can avoid the first statement and just specify the path name in constructor of XmlTextReader.

Petter Hesselberg
  • 5,062
  • 2
  • 24
  • 42
Vishal Kotak
  • 422
  • 4
  • 11
1

There are different ways, depending on where you want to get. XmlDocument is lighter than XDocument, but if you wish to verify minimalistically that a string contains XML, then regular expression is possibly the fastest and lightest choice you can make. For example, I have implemented Smoke Tests with SpecFlow for my API and I wish to test if one of the results in any valid XML - then I would use a regular expression. But if I need to extract values from this XML, then I would parse it with XDocument to do it faster and with less code. Or I would use XmlDocument if I have to work with a big XML (and sometimes I work with XML's that are around 1M lines, even more); then I could even read it line by line. Why? Try opening more than 800MB in private bytes in Visual Studio; even on production you should not have objects bigger than 2GB. You can with a twerk, but you should not. If you would have to parse a document, which contains A LOT of lines, then this documents would probably be CSV.

I have written this comment, because I see a lof of examples with XDocument. XDocument is not good for big documents, or when you only want to verify if there the content is XML valid. If you wish to check if the XML itself makes sense, then you need Schema.

I also downvoted the suggested answer, because I believe it needs the above information inside itself. Imagine I need to verify if 200M of XML, 10 times an hour, is valid XML. XDocument will waste a lof of resources.

prasanna venkatesh also states you could try filling the string to a dataset, it will indicate valid XML as well.

nkalfov
  • 439
  • 5
  • 12
1

Here is another approach using Cinchoo ETL - an open source library to parse xml file with few lines of code.

using (var r = ChoXmlReader<Item>.LoadText(xml)
       .WithXPath("//item")
      )
{
    foreach (var rec in r)
        rec.Print();
}

public class Item
{
    public string Name { get; set; }
    public string ProtectionLevel { get; set; }
    public string Description { get; set; }
}

Sample fiddle: https://dotnetfiddle.net/otYq5j

Disclaimer: I'm author of this library.

Cinchoo
  • 6,088
  • 2
  • 19
  • 34
0

If you want to retrive a particular value from an XML file

 XmlDocument _LocalInfo_Xml = new XmlDocument();
            _LocalInfo_Xml.Load(fileName);
            XmlElement _XmlElement;
            _XmlElement = _LocalInfo_Xml.GetElementsByTagName("UserId")[0] as XmlElement;
            string Value = _XmlElement.InnerText;
jithu
  • 1,867
  • 1
  • 7
  • 16