Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Linq;
- using System.Collections.Generic;
- using System.Xml.Serialization;
- using System.Diagnostics;
- namespace Core
- {
- /// <summary>
- /// Dictionary that can serialize/deserialize into a xml document
- /// </summary>
- [XmlRoot("dictionary")]
- [Serializable]
- public class SerializableDictionary<TKey,TValue>:Dictionary<TKey,TValue>,IXmlSerializable
- {
- #region Constructor
- public SerializableDictionary()
- {
- }
- public SerializableDictionary(IDictionary<TKey,TValue> dictionary)
- : base(dictionary)
- {
- }
- #endregion
- #region IXmlSerializable Members
- public System.Xml.Schema.XmlSchema GetSchema()
- {
- return null;
- }
- public void ReadXml(System.Xml.XmlReader reader)
- {
- if(reader.IsEmptyElement)
- return;
- XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
- Dictionary<Type,XmlSerializer> valueSerializersDict = new Dictionary<Type,XmlSerializer>();
- while(!reader.EOF)
- {
- reader.ReadToFollowing("item");
- string typeName = null;
- if(reader.HasAttributes)
- {
- bool found = reader.MoveToAttribute("type");
- if(found)
- {
- reader.ReadAttributeValue(); //<item type='' ...
- typeName = reader.Value;
- }
- }
- Type vtype = typeof(TValue);
- if(typeName != null)
- {
- vtype = Type.GetType(typeName);
- }
- TKey key = default(TKey);
- TValue value = default(TValue);
- if(reader.ReadToFollowing("key")) //<item><key...
- {
- object rawKey = reader.ReadString();
- if(typeof(TKey) == typeof(string))
- key = (TKey)rawKey;
- else
- key = (TKey)Convert.ChangeType(rawKey,typeof(TKey));
- }
- if(!reader.ReadToFollowing("value")) //<item><value...
- break; //no value; bad xml; so leave
- if(vtype.IsClass && vtype != typeof(string))
- {
- XmlSerializer vSerializer = null;
- //cache serializers
- if(!valueSerializersDict.TryGetValue(vtype,out vSerializer))
- {
- vSerializer = new XmlSerializer(vtype);
- valueSerializersDict.Add(vtype,vSerializer);
- }
- string rawxml = reader.ReadInnerXml();
- if(!string.IsNullOrEmpty(rawxml))
- {
- //deserialize value's type
- object rawvalue = null;
- using(System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(rawxml)))
- {
- System.Xml.XmlTextWriter xmlTextWriter = new System.Xml.XmlTextWriter(memoryStream,System.Text.Encoding.UTF8);
- rawvalue = vSerializer.Deserialize(memoryStream);
- }
- value = (TValue)rawvalue;
- }
- }
- else
- {
- object rawValue = reader.ReadString();
- if(typeof(TValue) == typeof(string))
- value = (TValue)rawValue;
- else
- value = (TValue)Convert.ChangeType(rawValue,vtype);
- }
- //add to dictionary
- this.Add(key,value);
- //skip any empty space
- reader.MoveToContent();
- if(reader.IsEmptyElement)
- break;
- }
- }
- public void WriteXml(System.Xml.XmlWriter writer)
- {
- XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
- XmlSerializer objectSerializer = new XmlSerializer(typeof(object));
- Dictionary<Type,XmlSerializer> serializerDict = new Dictionary<Type,XmlSerializer>();
- serializerDict.Add(typeof(TValue),new XmlSerializer(typeof(TValue)));
- System.Xml.Serialization.XmlSerializerNamespaces emptyNamespace = new System.Xml.Serialization.XmlSerializerNamespaces();
- emptyNamespace.Add(string.Empty,string.Empty);
- foreach(TKey key in this.Keys)
- {
- object value = this[key];
- Type vtype = value.GetType();
- string keyAsString = key.ToString();
- //start writing item element with type attribute <item type='valuetype'>
- writer.WriteStartElement("item");
- if(vtype.IsClass && vtype != typeof(string))
- writer.WriteAttributeString("type",vtype.AssemblyQualifiedName);
- else
- writer.WriteAttributeString("type",vtype.FullName);
- //start writing key element
- writer.WriteStartElement("key"); //<key>key value</key>
- writer.WriteString(keyAsString);
- writer.WriteEndElement();
- if(vtype.IsClass && vtype != typeof(string))
- {
- XmlSerializer vSerializer = null;
- if(!serializerDict.TryGetValue(vtype,out vSerializer))
- {
- vSerializer = new XmlSerializer(vtype);
- serializerDict.Add(vtype,vSerializer);
- }
- writer.WriteStartElement("value"); //<value><valueElement></valueElement></value>
- vSerializer.Serialize(writer,value,emptyNamespace);
- writer.WriteEndElement();
- }
- else
- {
- writer.WriteStartElement("value"); //<value>value</value>
- writer.WriteString(value.ToString());
- writer.WriteEndElement();
- }
- //end write item element
- writer.WriteEndElement();
- }
- }
- #endregion
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment