2017-03-11 75 views
0

我有兩個問題。我需要將數據序列化爲csv和xml,但它對我來說是有問題的。將數據序列化爲XML和CSV

爲XML我渴望得到的東西,如:

<sentence> 
<word>example1</word> 
<word>example2</word> 
<word>example3</word> 
</sentence> 
<sentence> 
<word>example1</word> 
<word>example2</word> 
<word>example3</word> 
</sentence> 

我的數據及其SentencedModel包含內部WordsModel的集合。所以它就像:List<ICollection<string>>.列表中的每個位置(句子)都有字符串(單詞)的集合。 類的樣子:

[Serializable] 
public class WordsModel : IEnumerable<string> 
{ 
    [XmlRoot("Word")] 
    public ICollection<string> Words { get; set;} 

    public IEnumerator<string> GetEnumerator() 
    { 
     return this.Words.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return this.Words.GetEnumerator(); 
    } 
} 

[Serializable] 
public class SentencedModel : IEnumerable<WordsModel> 
{ 
    [XmlArray("Sentence"), XmlArrayItem(typeof(WordsModel), ElementName = "Words")] 
    public ICollection<WordsModel> Sentences { get; set; } 

    public SentencedModel() 
    { 
     this.Sentences = new List<WordsModel>(); 
    } 

    public void Add(WordsModel words) 
    { 
     this.Sentences?.Add(words); 
    } 

    public IEnumerator<WordsModel> GetEnumerator() 
    { 
     return this.Sentences.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return this.Sentences.GetEnumerator(); 
    } 
} 

我的類,這是該庫:

public class WordsSeperapedBySentence 
{ 
    public SentencedModel WordsSeperatedBySentence { get; } 

    public WordsSeperapedBySentence() 
    { 
     this.WordsSeperatedBySentence = new SentencedModel(); 
    } 

    public bool AddSentence(ICollection<string> words) 
    { 
     if (words == null) return false; 
     WordsModel wordsModel = new WordsModel(); 
     wordsModel.Words = words; 
     this.WordsSeperatedBySentence.Add(wordsModel); 
     return true; 
    } 
} 

這裏是我的序列化器類:

public class SerializeData 
{ 
    public string SerializeToXml(SentencedModel data) 
    { 
     XmlSerializer xmlSerializer = new XmlSerializer(typeof(SentencedModel)); 
     using (StringWriter textWriter = new StringWriter()) 
     { 
      xmlSerializer.Serialize(textWriter, data); 
      return textWriter.ToString(); 
     } 
    } 

    public ToCsv(WordsSeperapedBySentence data) 
    { 
     //?? 
    } 
} 

但經過使用

List<string> example1 = new List<string>(); 
example1.Add("Chris"); 
example1.Add("call"); 
example1.Add("Anna"); 

List<string> example2 = new List<string>(); 
example2.Add("Somebody"); 
example2.Add("call"); 
example2.Add("Wolf"); 

WordsModel words1 = new WordsModel(); 
WordsModel words2 = new WordsModel(); 
words1.Words = example1; 
words2.Words = example2; 

SentencedModel sentenced = new SentencedModel(); 
sentenced.Add(words1); 
sentenced.Add(words2); 

SerializeData serialize = new SerializeData(); 
var stringAsResult = serialize.SerializeToXml(sentenced); 
Console.WriteLine(stringAsResult); 

我有錯誤。另外我不知道如何將它們存儲到CSV。 你能幫我嗎? 預先感謝您。

+0

'我有兩個problem'和'我得到了errors'是不是所有有幫助的,也不是在問兩個問題一個職位。寫入CSV應該像加入用','分開的單詞並寫出結果一樣簡單。 – Plutonix

+0

是的,這是真的。目前我已經找到了一些時間,並開始閱讀關於XmlBuilder。也許以後我會發布第二個問題給XML。 CSV已完成 –

回答

2

爲了您的數據保存爲CSV,你可以使用下面的方法,該方法提供了這樣的輸出:

Chris,call,Anna 
Somebody,call,Wolf 

每一行都是一個句子,然後所有的話都用逗號分隔。

public string ToCsv(SentencedModel data) 
{ 
    var csvLines = data.Select(x => String.Join(",", x)); 
    var csv = String.Join(Environment.NewLine, csvLines); 
    return csv; 
} 

我仍然缺少XML部分,如果我這樣做,我會編輯答案。 至少你有一部分。

編輯請在下面找到ToCsv,根據下面的註釋轉義字段。

public string ToCsv(SentencedModel data) 
{ 
    var csvLines = data.Sentences.Select(x => String.Join(",", x.Words.Select(w => EscapeForCsv(w)))); 
    var csv = String.Join(Environment.NewLine, csvLines); 
    return csv; 
} 

private string EscapeForCsv(string input) 
{ 
    return String.Format("\"{0}\"", input.Replace("\"", "\"\"\"")); 
} 
+1

對於csv,您可能想要補充的是,在某些情況下,需要引用字符串並在該字符串內引號,然後需要使用另一個引號進行轉義(請參閱http://stackoverflow.com/a/42719763/5708620) 。 –

+0

謝謝。爲了逃避一切,無論如何簡單的解決方案。您能否提供此CSV轉義規則的來源?我想進一步閱讀它。謝謝。 – StfBln

+1

csv沒有真正的標準,但RFC 4180解釋了它的大部分 - https://tools.ietf.org/html/rfc4180 –

0

第一:如果你要來標記文本 - 我建議:

  1. 使用一個數組,而不是一個列表。例如:string [] []。原因:列表會定位10%-20%以上的內存。可以通過.ToArray()(例如example1.ToArray)的列表轉換爲陣列,或使用C#6.0語法:

string[][] sentence = new [] { {"Chris","called","Anna"}, {"Somebody","called","Wolf"} };

  • 如果可能的:使用原始數據類型 - 類將複雜並放慢您的文本處理。
  • 第二:如果你想實現自己的串行試試這個approce:

    public abstract class AbstractSerializer 
    { 
        public abstract void Serialize(string[][] model, string path); 
    } 
    
    public class XmlSerializer : AbstractSerializer 
    { 
        public override void Serialize(string[][] model, string path) 
        { 
        // your stuff 
        } 
    } 
    
    public class CsvSerializer : AbstractSerializer 
    { 
        public string LineSeparator { get; set; } = "\r\n"; 
        public string ValueSeparator { get; set; } = ";"; 
    
        public override void Serialize(string[][] model, string path) 
        { 
        var stb = new System.Text.StringBuilder(); 
        for (int i = 0; i < model.Length; i++) 
        { 
         for (int j = 0; j < model[i].Length; j++) 
         { 
         // Example output: 
         // 0;0;Chris 
         // 0;1;call 
         // 0;2;Anna 
         // 1;0;Somebody 
         // 1;1;call 
         // 1;2;Wolf 
         stb.Append(string.Join(ValueSeparator, i, j, model[i][j], LineSeparator)); 
         } 
        } 
        } 
    }