Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to serialize an object collection / dictionary into <key>value</key>

Is there a way to serialize key/value pairs (preferably strongly typed, but possibly also sourced from a Dictionary) into the desired format below?

public List<Identifier> Identifiers = new List<Identifiers>();

public class Identifier
{
    public string Name { get; set; }
    public string Description { get; set; }
}

This normally serializes to the following:

<Identifiers>
  <Identifier>
    <Name>somename</Name>
    <Description>somedescription</Description>
  </Identifier>
  <Identifier>
    ...
  </Identifier>
</Identifiers>

The other possible approach we were thinking about is to use a hashtable/dictionary:

public Dictionary<string, string> Identifiers = new Dictionary<string,string>
{
    { "somename", "somedescription"},
    { "anothername", "anotherdescription" }
};

But this will either require a custom serialized Dictionary, or a custom XmlWriter.

The output we would like to achieve is:

<Identifiers>
  <somename>somedescription</somename>
  <anothername>anotherdescription</anothername>
</Identifiers>

So we're looking for code samples as to how best approach this to get the output we desire.

Edit: Maybe I should explain better. We already know how to serialize objects. What we are looking for is the answer to a particular type of serialization... I'll expand the question above

like image 774
mwjackson Avatar asked Sep 14 '12 09:09

mwjackson


People also ask

Can I serialize a dictionary?

NET objects is made easy by using the various serializer classes that it provides. But serialization of a Dictionary object is not that easy. For this, you have to create a special Dictionary class which is able to serialize itself. The serialization technique might be different in different business cases.

Can dictionary be serialized in C#?

Dictionary can't be serialized as a document.

Can JSON serialize dictionary?

The built-in JSON serializer in .


2 Answers

It is easy with LINQ to XML:

Dictionary<string, string> Identifiers = new Dictionary<string,string>()
{
    { "somename", "somedescription"},
    { "anothername", "anotherdescription" }
};

XElement xElem = new XElement("Identifiers",
                               Identifiers.Select(x=>new XElement(x.Key,x.Value)));

string xml = xElem.ToString(); //xElem.Save(.....);

OUTPUT:

<Identifiers>
  <somename>somedescription</somename>
  <anothername>anotherdescription</anothername>
</Identifiers>
like image 175
L.B Avatar answered Oct 24 '22 18:10

L.B


This is hard to answer as you don't really clarify what 'best' means to you.

Fastest would probably be the raw write out as strings:

var sb = new StringBuilder();
sb.Append("<identifiers>");
foreach(var pair in identifiers)
{
    sb.AppendFormat("<{0}>{1}</{0}>", pair.Key, pair.Value);
}
sb.Append("</identifiers>");

Obviously that's not handling any escaping to XML, but then that might not be a problem, it depends entirely on the contents of your dictionary.

What about fewest lines of code? If that's your requirement then L.B.'s Linq to XML answer's probably best.

What about smallest memory footprint? There I'd look at dropping the Dictionary and creating your own serialisable class that drops the hash overhead and collection functionality in favour of just storing name and value. That might be fastest too.

If code simplicity is your requirement then how about using dynamic or anonymous types instead of Dictionary?

var anonType = new
{ 
    somename = "somedescription",
    anothername = "anotherdescription" 
}

// Strongly typed at compile time
anonType.anothername = "new value";

That way you're not dealing with 'magic strings' for the names of properties in your collection - it will be strongly typed in your code (if that's important for you).

However anonymous types don't have a built in serialiser - you'd have to write something for yourself, use one of the many open source alternatives or even use the XmlMediaTypeFormatter.

There are loads of ways to do this, which one is best depends on how you're going to use it.

like image 31
Keith Avatar answered Oct 24 '22 18:10

Keith