【问题标题】:Serialize data to XML and CSV将数据序列化为 XML 和 CSV
【发布时间】:2017-03-11 16:07:43
【问题描述】:

我有两个问题。我需要将数据序列化为 csv 和 xml,但结果对我来说是个问题。

作为 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&lt;ICollection&lt;string&gt;&gt;. 列表中的每个位置(句子)都有字符串(单词)的集合。 类看起来像:

[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。 你可以帮帮我吗? 提前谢谢你。

【问题讨论】:

  • I have two problemI got errors 根本没有帮助,在一篇文章中问两个问题也没有帮助。写入 CSV 应该像连接由 , 分隔的单词并写出结果一样简单。
  • 是的,这是真的。目前我已经找到一些时间并开始阅读有关 XmlBuilder 的信息。也许稍后我会将第二个问题发布到 XML。 CSV 完成

标签: c# xml csv serialization


【解决方案1】:

为了将您的数据保存为 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下方找到根据下面的cmets进行转义的字段。

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("\"", "\"\"\""));
}

【讨论】:

  • 对于 csv,您可能需要补充一点,在某些情况下,字符串需要被引用,并且该字符串中的引号需要用另一个引号转义(参见 stackoverflow.com/a/42719763/5708620)。
  • 谢谢。去寻找逃避一切的简单解决方案。您能否提供此 CSV 转义规则的来源?我想进一步了解它。谢谢。
  • 没有真正的 csv 标准,但 RFC 4180 解释了大部分 - tools.ietf.org/html/rfc4180
【解决方案2】:

首先:如果您想标记文本 - 我建议:

  1. 使用数组而不是列表。例如:字符串[][]。原因:List 会多定位 10%-20% 的内存。您可以通过 .ToArray()(例如 example1.ToArray)将 List 转换为 Array 或使用 C# 6.0 语法:

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

  1. 如果可能:使用原始数据类型 - 类会使您的文本处理变得复杂并减慢速度。

第二:如果你想实现自己的序列化器,试试这个方法:

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));
      }
    }
  }
}

【讨论】:

    猜你喜欢
    • 2021-04-25
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 2017-01-04
    • 1970-01-01
    • 1970-01-01
    • 2016-10-24
    相关资源
    最近更新 更多