Reading and Writing XML File in .NET

SheoNarayan
Posted by in .NET Framework category on for Intermediate level | Views : 26550 red flag
Rating: 3 out of 5  
 1 vote(s)

This article describes how to create XML file and also shows various ways of reading XML File in .NET using XmlTextReader, XmlDocumenet, XPathDocument, DataSet and XmlDataSource control.
Introduction
In todays world of software development, its tough to escape from XML data. In this article, I have tried to describe briefly how to create XML file and also how to read it using different inbuilt classes provided in .NET Framework.  

Lets start this by creating an xml document first and then we will see how to read them. In general, to work with XML document, you need to use System.Xml namespace.

Creating XML File

To create XML file, you can use XmlTextWriter. In following code-snippet, I have instantiated XmlTextWriter class and passed two parameter, filename and encoding type to use while creating XML file.

string fileName = Server.MapPath("~/App_Data/XMLFile.xml");

XmlTextWriter writer = new XmlTextWriter(fileName, System.Text.Encoding.UTF8);

try

{

writer.WriteStartDocument(); // writes to top element - version and encoding type

writer.WriteStartElement("Details"); // write start parent element

// write 1st record data

writer.WriteStartElement("Person"); // write start element inside parent - Person

writer.WriteAttributeString("Name", "Ram"); // writes attribute and its value

writer.WriteAttributeString("Address", "Ram Nagar"); // same as previous line

writer.WriteString("Ram is a very good boy <br />He lives in Ram Nagar"); // write element value inside Person element

writer.WriteEndElement(); // write end element inside parent - Person

// write 2nd record data

writer.WriteStartElement("Person");

writer.WriteAttributeString("Name", "Shyam");

writer.WriteAttributeString("Address", "Shyam Nagar");

writer.WriteString("Shyam is a very good boy <br />He lives in Shyam Nagar");

writer.WriteEndElement();

writer.WriteEndElement(); // end parent element

writer.WriteEndDocument(); // end top element

}

catch

{

throw;

}

finally

{

writer.Close();

}

Above code-snippet will create a file named XMLFile.xml that will have following contents.

<?xml version="1.0" encoding="utf-8"?>

<Details>

<Person Name="Ram" Address="Ram Nagar">Ram is a very good boy &lt;br /&gt;He lives in Ram Nagar</Person>

<Person Name="Shyam" Address="Shyam Nagar">Shyam is a very good boy &lt;br /&gt;He lives in Shyam Nagar</Person>

</Details>

You must have noticed in any standard XML file that first element contains information about XML version and encoding type used to write data in the file. To store data into XML file, you should specify the parent element that can hold n number of data for a particular entity (in this case Person). You can understand it like this - To store data into the database, you need a table and then you add records into that table. So in perspective of this xml file, the file itself is database, Details is the table and Person is every records in the Details table.

There are two ways you can store data into XML file.

  1. As as attribute of the element - In this cas I have stored Name and Address as attribute of the Person element
  2. As inner text of the element - In this case I have stored long text about that person.

Above code-snippet is self explanatory, however in briefly XmlTextWriter's method:

  • WriteStartDocument writes version and encoding type - the top level element.
  • WriteEndDocument writes end of the document, if any
  • WriteStartElement writes start element with the string you pass as parameter.
  • WriteAttributeString writes the name of the attribute and its value.
  • WriteString writes any string you pass as innertext of the element.
  • WriteEndElement write end element, this follows the herarchy, so be careful. You can't use it without using WriteStartElement method.

 

Reading XML File

There are several ways to read the XML File. 

Using XmlReader

To read the XML File using XmlReader, you need to use XmlTextReader and pass file name as parameter. In the following code-snippet, I have used ReadToFollowing method in while loop to loop through all elements having element name as Person. Using GetAttribute name I got the value of the attributes (Name and Address) and using ReadString, I got the innertext data for that element.

StringBuilder strB = new StringBuilder("<b>Using XML Reader</b> <br />", 500);

XmlReader reader = new XmlTextReader(fileName);

try

{

while(reader.ReadToFollowing("Person"))

{

strB.Append("Name: " + reader.GetAttribute("Name").ToString());

strB.Append(" | Address: " + reader.GetAttribute("Address").ToString());

strB.Append(" | Descriptions: " + reader.ReadString());

strB.Append("<hr />");

}

}

catch

{

throw;

}

finally

{

reader.Close();

}

 



 

Using XmlDocument

Instantiate the XmlDocument class and use Load method by passing xml file name as parameter. To loop through all nodes of the document, use SelectNodes and pass xml path as parameter (Details/Person - Details is the parent node and Person is the chid node). Use GetAttribute method, to get the value of the attribute and to get innertext data, use InnerText.

XmlDocument doc = new XmlDocument();

try

{

doc.Load(fileName);

foreach (XmlElement elements in doc.SelectNodes("Details/Person"))

{

strB.Append("Name: " + elements.GetAttribute("Name"));

strB.Append("Name: " + elements.GetAttribute("Address"));

strB.Append(" | Descriptions: " + elements.InnerText);

strB.Append("<hr />");

}

}

finally

{

doc = null;

}

Using XPathDocument

In order to use XPathDocument class, you need to use System.Xml.XPath namespace, this is faster than XmlDocument, however the coding is a bit different and bit more than XmlDocument. First instantiate XPathDocument class and pass xml file name as parameter. Create a navigator using CreateNavigator method of the XPathDocument object that will return XPathNavigator object. Use Select method of the navigator object to return the iterator (XPathNodeIterator) object. Loop through the iterator and get the value of the attribute using GetAttribute method and get innertext data using Value. As this is the iterator object so you need to ensure that you are using Current node to get your data.

System.Xml.XPath.XPathDocument xDoc = new System.Xml.XPath.XPathDocument(fileName);

System.Xml.XPath.XPathNavigator nav = xDoc.CreateNavigator();

System.Xml.XPath.XPathNodeIterator iterator = nav.Select("Details/Person");

while(iterator.MoveNext())

{

strB.Append("Name: " + iterator.Current.GetAttribute("Name", ""));

strB.Append("Name: " + iterator.Current.GetAttribute("Address", ""));

strB.Append(" | Descriptions: " + iterator.Current.Value);

strB.Append("<hr />");

}

Using DataSet

This is another way of reading Xml file. Simply instantiate DataSet object and pass xml file name as parameter to the ReadXml method.

DataSet dSet = new DataSet();

try

{

dSet.ReadXml(fileName);

GridView1.DataSource = dSet.Tables[0].DefaultView;

GridView1.DataBind();

}

finally

{

dSet.Dispose();

}

You must have noticed that DataTable has also ReadXml method to read XML file provided you have xml schema with it. Without xml schema information, DataTable can't read the XML file.

Using XmlDataSource

There are certain limitations while using XmlDataSource control to read XML, you should use this when you have all data in the XML file as an attributes of the element not inside the element (as innertext). This is generally useful when you want to populate any Data Controls like GridView, DataList etc.

XmlDataSource xmlSource = new XmlDataSource();

xmlSource.DataFile = fileName;

xmlSource.XPath = "Details/Person";

GridView2.DataSource = xmlSource;

GridView2.DataBind();

Validating XML
To validate the XML file against its schema (to generate valid schema from an xml, you can read http://davidhayden.com/blog/dave/archive/2006/04/22/2921.aspx article), following function can be used. First read the xml file into the string variable by using any of the way described above and use following function to validate against its schema. This function accepts xmlString as parameter and return true if the xml string passed the schema validation else it returns false.
private bool IsXmlValidString(string xmlString)
{
bool toReturn = false;
XmlSchemaSet schemaSet = new XmlSchemaSet();
schemaSet.Add("", XmlReader.Create(Server.MapPath("~/MyXmlSchema.xsd")));
using (TextReader xmlData = new StringReader(xmlString))
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add(schemaSet);
settings.ValidationType = ValidationType.Schema;
using (XmlReader xmlRead = XmlReader.Create(xmlData, settings))
{
try
{
while (xmlRead.Read())
{
}

toReturn = true;
}
catch
{
toReturn = false;
}
}
}
return toReturn;
}
Conclusion

In this article, I described how to create and read xml file. You can use any of the way described above to read XML file if it suits your requiremets, however they have their pros and cons. Generally, XmlTextReader is much much faster than any other way of reading xml data. You can refer to this article for the best practices of XML in .NET.

Hope this will be useful. Thanks and enjoy XML :).

Page copy protected against web site content infringement by Copyscape

About the Author

SheoNarayan
Full Name: Sheo Narayan
Member Level: HonoraryPlatinum
Member Status: Administrator
Member Since: 7/8/2008 6:32:14 PM
Country: India
Regards, Sheo Narayan http://www.dotnetfunda.com
http://www.snarayan.com
Ex-Microsoft MVP, Author, Writer, Mentor & architecting applications since year 2001. Connect me on http://www.facebook.com/sheo.narayan | https://twitter.com/sheonarayan | http://www.linkedin.com/in/sheonarayan

Login to vote for this post.

Comments or Responses

Posted by: Raja on: 12/18/2008
What a consolidated article on working with XML !!!

Excellent Sheo Narayan !!! Keep it up.

Login to post response

Comment using Facebook(Author doesn't get notification)