Do you need to treat one of the columns specially to be the XAttribute instead of XElement? If not, this can be simplified...
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
namespace ConsoleApplication6
{
class Program
{
public static Dictionary<TKey, TValue> ZipIntoDictionary<TKey, TValue>(Dictionary<TKey, TValue> dict, IEnumerable<TKey> keys, IEnumerable<TValue> values)
{
dict = dict ?? new Dictionary<TKey, TValue>();
var enumKeys = keys.GetEnumerator();
var enumValues = values.GetEnumerator();
while (enumKeys.MoveNext() && enumValues.MoveNext())
{
dict.Add(enumKeys.Current, enumValues.Current);
}
return dict;
}
static void Main(string[] args)
{
string filePath = "customers.csv";
List<string> headers = null;
const string idKey = "CustomerID";
Dictionary<string, string> columns = null;
XElement customers = new XElement("Root");
using (StreamReader sr = new StreamReader(filePath))
{
string line;
while ((line = sr.ReadLine()) != null)
{
if (string.IsNullOrWhiteSpace(line))
continue;
string[] rawColumns = line.Split(',');
if (headers == null)
{
headers = rawColumns.ToList();
if (!headers.Contains(idKey))
{
Console.WriteLine("Missing Identifier Key: " + idKey);
return;
}
continue;
}
columns = ZipIntoDictionary(columns, headers, rawColumns);
XElement thisCustomer = new XElement("Customer", new XAttribute(idKey, columns[idKey]));
foreach (var pair in columns)
{
if (pair.Key != idKey)
thisCustomer.Add(new XElement(pair.Key, pair.Value));
}
customers.Add(thisCustomer);
}
}
Console.WriteLine(customers);
}
}
}
Most/all of the hard-coded strings could/should be passed as arguments.
[Edit: MTH]
Here it is a bit simplified for no attribute...
static void Main(string[] args)
{
string filePath = "customers.csv";
XElement customers = CsvToXml(filePath, "Root", "Customer");
Console.WriteLine(customers);
}
static XElement CsvToXml(string filePath, string rootName, string elementName)
{
string[] headers = null;
XElement root = new XElement(rootName);
using (StreamReader sr = new StreamReader(filePath))
{
string line;
while ((line = sr.ReadLine()) != null)
{
if (string.IsNullOrWhiteSpace(line))
continue;
string[] columns = line.Split(',');
if (headers == null)
{
headers = columns;
continue;
}
XElement thisElement = new XElement(elementName);
for (int i = 0; i < headers.Length; i++)
{
string value = string.Empty;
if (i < columns.Length)
value = columns[i];
thisElement.Add(new XElement(headers[i], value));
}
root.Add(thisElement);
}
}
return root;
}