Introduction
I had a simple requirement yesterday to read an XML file, change a date field and save. This was a very simple task, but I had to refresh my XML basics and figure out how to change its contents which still took me an hour. There seem to be hundreds of web posts on XML reader issues, resolution, and altenatives but I wanted to post my simple method on doing this. I wrote 2 overloaded methods. The first takes a file name string
parameter and simply reads XML file to return date value from an element. The second takes file name string
and datetime
parameter, changes the required field in XML file and save.
Using the Code
Here is the XML file:
="1.0"="utf-8"
<ROOT>
<CLASS PROCESSINGDATE="20152101" CLASSID="6">
<FIELD FLDDATA="1" FLDNAME="CLASSTYPE" />
<FIELD FLDDATA="2" FLDNAME="CLASSTYPECODE" />
<FIELD FLDDATA="3" FLDNAME="CLASSTYPESUBCODE" />
</CLASS>
</ROOT>
<CLASS>
= element
<PROCESSINGDATE>
= attribute
<FIELD>
= sub-element
In another method, ProcessingDateTime
field is read as string
from XML file so it is converted to standard date format.
retProcDate = Convert.ToDateTime(pdate.Substring(4, 2) + "/" +
pdate.Substring(6, 2) + "/" + pdate.Substring(0, 4));
For the first requirement, date had to be formatted as yyyyMMdd
before saving.
In order to access other fields/attributes of the class element, simply change to ["CLASSID"].Value
.
xd.DocumentElement.FirstChild.Attributes["PROCESSINGDATE"].Value =
String.Format("{0:yyyyMMdd}", dtProcDate);
Here is a great reference site when working with String Format
for DateTime
.
http://www.csharp-examples.net/string-format-datetime/
Here is the full code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.IO;
namespace ReadXMLDate
{
class Program
{
static void Main(string[] args)
{
const string FName = "C:\\Class.xml";
DateTime NewDate = DateTime.Now;
ReadDateFromXML(FName, NewDate);
NewDate = ReadDateFromXML(FName);
}
private static void ReadDateFromXML(string filename, DateTime dtProcDate)
{
if (File.Exists(filename))
{
XmlDocument xd = new XmlDocument();
xd.Load(filename);
xd.DocumentElement.FirstChild.Attributes["PROCESSINGDATE"].Value =
String.Format("{0:yyyyMMdd}", dtProcDate);
xd.Save(filename);
}
}
private static DateTime ReadDateFromXML(string filename)
{
DateTime retProcDate = new DateTime();
if (File.Exists(filename))
{
XmlDocument xd = new XmlDocument();
xd.Load(filename);
string pdate = xd.DocumentElement.FirstChild.Attributes["PROCESSINGDATE"].Value;
if (!string.IsNullOrEmpty(pdate))
{
retProcDate = Convert.ToDateTime
(pdate.Substring(4, 2) + "/" + pdate.Substring(6, 2) + "/" +
pdate.Substring(0, 4));
}
}
return retProcDate;
}
}
}
Points of Interest
Before I was using XmlReader
but encountered this error when trying to read the file.
XmlReader xmlReader = XmlReader.Create(new StringReader(filename));
while (xmlReader.Read())
XmlReader
wasn't loading and encountered unhandled XmlException
.
Data at the root level is invalid. Line 1, position 1.
Instead of chasing it, I used XML Load
property which worked without any issues.
History
No updates yet. Suggestions are welcome.