Bartosz Kowalczyk Bartosz Kowalczyk - 9 months ago 41
C# Question

Serialize data to XML and CSV

I have two problem. I need to serialize data to csv and xml but its turn out to be problematic for me.

As xml I desire to get something like:

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


My data its SentencedModel which contain inside collection of WordsModel. So it like:
List<ICollection<string>>.
Every position (sentence) in list have collection of string (words).
Class look like:

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


My class which is Repositories for that:

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


Here is my serializer class:

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)
{
//??
}
}


But after using

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


I got errors. Also I do not have idea how to storage them to CSV.
Could you help me?
Thank you in advance.

Answer Source

In order to save your data as CSV, you can use the following method which provides this output:

Chris,call,Anna
Somebody,call,Wolf

Each line is a sentence then all the words are separated by commas.

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

I am still missing the XML part, if I do, I will edit the answer. At least you have a part of it.

Edit Please find below the ToCsv with the fields being escaped based on the comments below.

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