Friday, March 7, 2008

Serializable Dictionary

Some quick code for a VB.Net dictionary object which can be serialized to XML. Most of the credit goes to Paul Welter, who covers a C# implementation here.

This code is a port to VB with some minor structure changes. In Paul's example, each key/value pair is contained within <item> tags; in this version, the key is typed as a string and used as the tag. For our uses, this was simpler and resulted in slightly more readable XML output.

Imports System.Xml.Serialization

Public Class XmlDictionary(Of T)
Inherits Dictionary(Of String, T)
Implements IXmlSerializable


Public Function GetSchema() As System.Xml.Schema.XmlSchema Implements IXmlSerializable.GetSchema
Return Nothing
End Function

Public Sub ReadXml(ByVal reader As System.Xml.XmlReader) Implements IXmlSerializable.ReadXml
Dim valSerializer As New XmlSerializer(GetType(T))

Dim wasEmpty As Boolean = reader.IsEmptyElement
reader.Read()

If (wasEmpty) Then Return

While reader.NodeType <> Xml.XmlNodeType.EndElement

Dim key As String = reader.Name
reader.ReadStartElement()
Dim value As T = valSerializer.Deserialize(reader.ReadSubtree())
reader.ReadEndElement()

Me.Add(key, value)

reader.ReadEndElement()
reader.MoveToContent()

End While

reader.ReadEndElement()

End Sub

Public Sub WriteXml(ByVal writer As System.Xml.XmlWriter) Implements IXmlSerializable.WriteXml

Dim valSerializer As New XmlSerializer(GetType(T))

For Each key As String In Me.Keys
writer.WriteStartElement(key)

Dim value As T = Me(key)
valSerializer.Serialize(writer, value)

writer.WriteEndElement()
Next

End Sub

End Class


The resulting XML will look as follows:

<?xml version="1.0"?>
<XmlDictionaryOfString>
<key1>
<string>val1</string>
</key1>
<key2>
<string>val2</string>
</key2>
<key3>
<string>val3</string>
</key3>
</XmlDictionaryOfString>


Note that the values are serialized and need not be strings. You may wish to check out Paul's code if you need non-string keys.