This is from the docs:
CSV:
Id,Name
1,one
2,two
Column definitions:
public class Foo
{
[Index(0)]
public int Id { get; set; }
[Index(1)]
public string Name { get; set; }
}
Reader:
using (var reader = new StreamReader("path\\to\\file.csv"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
var records = csv.GetRecords<Foo>();
foreach (var record in records)
{
//record.Id
//record.1
//record.2
}
}
It is straightforward enough to access a field value by using the column ID. But, I have a situation where I want to loop all the fields in the record
and get the field value by column index:
record.GetField(columnIndex)
At this point in time, how can I obtain the column heading value for this column index? I want to know it so that I can create a XmlElement
based on the name of the column heading.
Maybe reflection can help you here. If you want to find from index specifically you can refactor this into what you need exactly but here's the principle. You can then build your xml object from the values.
foreach (var record in records)
{
var properties = record.GetType().GetProperties();
foreach (var property in properties)
{
var propertyName = property.Name;
var propertyValue = property.GetValue(record);
....
This being said, I think its better to separate the CSV read from your conversion to XML. This also means it can be reusable ie.
public string ToXml<T>(T data)
{
XmlSerializer ser = new XmlSerializer(typeof(T));
var xml = string.Empty;
using (var sww = new StringWriter())
{
using (XmlWriter writer = XmlWriter.Create(sww))
{
ser.Serialize(writer, data);
xml = sww.ToString();
}
}
return xml;
}
public List<T> ReadCsv<T>(string filePath)
{
using (var reader = new StreamReader(filePath))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
return csv.GetRecords<T>().ToList();
}
}
This can be used like
var data = ReadCsv<Foo>("pathToFile");
var xml = ToXml(data);
You could even go one step further and define the ToXml as an object extension (here is a link to some documentation for completeness: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods)
public static class ObjectExtensions
{
public static string ToXml<T>(this T data)
{
XmlSerializer ser = new XmlSerializer(typeof(T));
var xml = string.Empty;
using (var sww = new StringWriter())
{
using (XmlWriter writer = XmlWriter.Create(sww))
{
ser.Serialize(writer, data);
xml = sww.ToString();
}
}
return xml;
}
}
You can now do
var data = ReadCsv<Foo>("pathToFile");
var xml = data.ToXml();