2010-06-18 136 views
8

我需要將CSV轉換爲XML文檔。到目前爲止,我看到的例子都顯示瞭如何在CSV中使用固定數量的列來完成此操作。將CSV文件轉換爲XML

我有這個迄今爲止,使用LINQ:

String[] File = File.ReadAllLines(@"C:\text.csv"); 

     String xml = ""; 

     XElement top = new XElement("TopElement", 

     from items in File 

     let fields = items.Split(';') 

     select new XElement("Item", 

     new XElement("Column1", fields[0]), 

     new XElement("Column2", fields[1]), 

     new XElement("Column3", fields[2]), 

     new XElement("Column4", fields[3]), 

     new XElement("Column5", fields[4]) 

     ) 

     ); 

     File.WriteAllText(@"C:\xmlout.xml", xml + top.ToString()); 

這是列的固定金額,但我.CSV具有不同數量的每一行的列。

根據每個.CSV行中有多少個單詞(列),你如何適應某種循環?

日Thnx

回答

23
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"); 

輸入:

A;B;C 
D;E;F 
G;H 

輸出:

<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> 
+0

非常接近。但是我需要在每行分開的前面加上一個單詞; 因此,輸出XML會是這個樣子: 我幾乎與我貼的代碼了,但我只拿到每行第一個字。所以我需要添加一些循環,爲a中的每行添加一個Column元素; – Soeren 2010-06-18 13:13:30

+0

@Soeren:那不是我的解決方案嗎?我已經添加了一個澄清示例。 – dtb 2010-06-18 18:11:36

+0

這很好。 line.Split(';')部分不在第一個示例中,我試圖自己添加它。我只是不知道如何添加它。我需要再研究一下這個LINQ的東西。謝謝你的幫助。 – Soeren 2010-06-18 19:06:03

9

如果您想使用的標題作爲元素名稱:

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"); 
+0

有沒有辦法將此示例轉換爲JSON? – Alao 2014-11-30 14:33:13

3

我寫了一個派生自Vlax的片段的類。另外我還提供了一個單元測試來記錄工作流程。

單元測試:

[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到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; 
    } 
} 

注:

我通過爲每個刪除後面的逗號擴展明經的解決方案導致運行時異常ba的CSV行條目sed的索引超出了與列標題相關的界限。

+1

很好的實現! – LordTitiKaka 2014-12-21 10:07:11