Tuesday, 28 January 2014

Converting CSV to XML and then to C# Object List

Recently I was working on a project where I had to convert a CSV file to XML.
CSV was generated from a database table. Later that XML has to be converted to C# list and used in the project as setting values.

I'll use a sample csv data here that contains information about few students like their roll number, name and marks in various subjects

Create a C# Console application and add csv file in Resources folder. I'm naming it StudentMarks.csv.

roll_no name physics chemistry maths biology english
1 Abhinav 83 80 89 79 92
2 Chang 78 64 94 72 83
3 Dexter 75 86 79 92 68
4 Francis 68 91 64 94 72
5 Glen 80 89 79 93 56
6 Harry 52 87 86 79 92
7 Kapil 98 79 92 79 92
8 Manoj 79 92 89 89 91
9 Preeti 98 97 93 95 93
10 Sonia 65 75 80 89 79


Open Properties of StudentMarks.csv by right clicking on it. Then change value of Copy to Output Directory to Copy Always.
Then we will create a Student Class
Now in the MainProgram.cs create a method to convert CSV to XML. It accepts two paramters one for input csvFilePath and other for output xmlFilePath

public static void convertCsvToXml(string csvFilePath, string xmlFilePath)
{
var lines = File.ReadAllLines(csvFilePath);
//Getting header values from first line
string[] headers = lines[0].Split(',').Select(x => x).ToArray();
var xml = new XElement("StudentMarks",
lines.Where((line, index) => index > 0)
.Select((line, i) => new XElement("Student",
line.Split(',').Select((column, index) => new XElement(headers[index], column)))));
xml.Save(xmlFilePath);
}
view raw MainProgram.cs hosted with ❤ by GitHub
First we are reading all the lines of csv file as list of strings. Then we will extract the header values from first line which will be used as xml attributes for data values. After that we will convert rest of the lines into XElement object and use the extracted header values to create xml attributes.
The Resulting XML will look like following

<?xml version="1.0" encoding="utf-8"?>
<StudentMarks>
<Student>
<roll_no>1</roll_no>
<name>Abhinav</name>
<physics>83</physics>
<chemistry>80</chemistry>
<maths>89</maths>
<biology>79</biology>
<english>92</english>
</Student>
...
</StudentMarks>
view raw gistfile1.xml hosted with ❤ by GitHub

Now add one more method to convert from XML to C# list. This method accepts filepath of XML file and returns List of Students Object.
Here we will use XDocument class to load XML values and then Linq query to get the list.

public static List<Student> convertXMLtoList(string filePath)
{
XDocument doc = XDocument.Load(filePath);
List<Student> studentsMarks = doc.Descendants("Student").Select(x => new Student()
{
RollNo = int.Parse(x.Element("roll_no").Value),
Name = x.Element("name").Value,
Physics = short.Parse(x.Element("physics").Value),
Chemistry = short.Parse(x.Element("chemistry").Value),
Maths = short.Parse(x.Element("maths").Value),
Biology = short.Parse(x.Element("biology").Value),
English = short.Parse(x.Element("english").Value)
}).ToList();
return studentsMarks;
}
view raw MainProgram.cs hosted with ❤ by GitHub
Now from the Main Method call above created methods with proper parameter values.
static void Main(string[] args)
{
//Both the paths points to bin\debug folder of project
string csvFilePath = @".\Resources\StudentMarks.csv";
string xmlFilePath = @".\Resources\StudentMarks.xml";
//Converting CSV to XML, comment out after running once.
convertCsvToXml(csvFilePath, xmlFilePath);
//Converting XML to C# List
var studentsMarks = convertXMLtoList(xmlFilePath);
//For verification
foreach (var student in studentsMarks)
{
Console.Out.WriteLine(student.Name);
}
}
view raw MainProgram.cs hosted with ❤ by GitHub
That’s it. I've shared the solution folder at https://github.com/kushdilip/CSharp_Experiments/.

 For any doubts please comment.
 

No comments:

Post a Comment