2017-03-11 46 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)); 
         } 
        } 
        } 
    }