Convert CSV file to XML Convert CSV file to XML xml xml

Convert CSV file to XML


var lines = File.ReadAllLines(@"C:\text.csv");var xml = new XElement("TopElement",   lines.Select(line => new XElement("Item",      line.Split(';')          .Select((column, index) => new XElement("Column" + index, column)))));xml.Save(@"C:\xmlout.xml");

Input:

A;B;CD;E;FG;H

Output:

<TopElement>  <Item>    <Column0>A</Column0>    <Column1>B</Column1>    <Column2>C</Column2>  </Item>  <Item>    <Column0>D</Column0>    <Column1>E</Column1>    <Column2>F</Column2>  </Item>  <Item>    <Column0>G</Column0>    <Column1>H</Column1>  </Item></TopElement>


In case you want use the headers as the elements names:

var lines = File.ReadAllLines(@"C:\text.csv");string[] headers = lines[0].Split(',').Select(x => x.Trim('\"')).ToArray();var xml = new XElement("TopElement",   lines.Where((line, index) => index > 0).Select(line => new XElement("Item",      line.Split(',').Select((column, index) => new XElement(headers[index], column)))));xml.Save(@"C:\xmlout.xml");


I wrote a class that derives from Vlax's snippet.In addition I have provided a unit test to document the workflow.

Unit Test:

[TestMethod]public void convert_csv_to_xml(){    // Setup    var csvPath = @"Testware\vendor.csv";    var xmlPath = @"Testware\vendor.xml";    // Test    var success = DocumentConverter.Instance.CsvToXml(csvPath, xmlPath);    // Verify    var expected = File.Exists(xmlPath) && success;    Assert.AreEqual(true, expected);}

CSV to XML:

public class DocumentConverter{    #region Singleton    static DocumentConverter _documentConverter = null;    private DocumentConverter() { }    public static DocumentConverter Instance    {        get        {            if (_documentConverter == null)            {                _documentConverter = new DocumentConverter();            }            return _documentConverter;        }    }    #endregion    public bool CsvToXml(string sourcePath, string destinationPath)    {        var success = false;        var fileExists = File.Exists(sourcePath);        if (!fileExists)        {            return success;        }        var formatedLines = LoadCsv(sourcePath);        var headers = formatedLines[0].Split(',').Select(x => x.Trim('\"').Replace(" ", string.Empty)).ToArray();        var xml = new XElement("VendorParts",           formatedLines.Where((line, index) => index > 0).               Select(line => new XElement("Part",                  line.Split(',').Select((field, index) => new XElement(headers[index], field)))));        try        {            xml.Save(destinationPath);            success = true;        }        catch (Exception ex)        {            success = false;            var baseException = ex.GetBaseException();            Debug.Write(baseException.Message);        }        return success;    }    private List<string> LoadCsv(string sourcePath)    {        var lines = File.ReadAllLines(sourcePath).ToList();        var formatedLines = new List<string>();        foreach (var line in lines)        {            var formatedLine = line.TrimEnd(',');            formatedLines.Add(formatedLine);        }        return formatedLines;    }}

NOTE:

I extended Vlax's solution by removing a trailing comma for each of the CSV line entries that caused a runtime exception based on an index being out of bounds in relation to the column header.