如何XML序列化字典
我已经能够以这种方式序列化IEnumerable:
[XmlArray("TRANSACTIONS")] [XmlArrayItem("TRANSACTION", typeof(Record))] public IEnumerable Records { get { foreach(Record br in _budget) { yield return br; } } }
但是,我意识到现在我需要一个包含集合Dictionary
(RecordCollection实现IEnumerable)的Dictionary
。
我怎样才能做到这一点?
看看以下博客文章
-
http://blogs.msdn.com/b/psheill/archive/2005/04/09/406823.aspx - http://web.archive.org/web/20100703052446/http://blogs.msdn.com/b/psheill/archive/2005/04/09/406823.aspx
这个(不是英文,但代码很有用)
我已经使用了以下一段时间了。 它最初来自这里 。
namespace SerializeDictionary { using System; using System.Collections.Generic; using System.Runtime.Serialization; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; /// /// Represents an XML serializable collection of keys and values. /// /// The type of the keys in the dictionary. /// The type of the values in the dictionary. [Serializable] [XmlRoot("dictionary")] public class SerializableDictionary : Dictionary, IXmlSerializable { /// /// The default XML tag name for an item. /// private const string DefaultItemTag = "item"; /// /// The default XML tag name for a key. /// private const string DefaultKeyTag = "key"; /// /// The default XML tag name for a value. /// private const string DefaultValueTag = "value"; /// /// The XML serializer for the key type. /// private static readonly XmlSerializer keySerializer = new XmlSerializer(typeof(TKey)); /// /// The XML serializer for the value type. /// private static readonly XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue)); /// /// Initializes a new instance of the /// class. /// public SerializableDictionary() { } /// /// Initializes a new instance of the /// class. /// /// A /// object /// containing the information required to serialize the /// . /// /// A /// structure /// containing the source and destination of the serialized stream /// associated with the /// . /// protected SerializableDictionary(SerializationInfo info, StreamingContext context) : base(info, context) { } /// /// Gets the XML tag name for an item. /// protected virtual string ItemTagName { get { return DefaultItemTag; } } /// /// Gets the XML tag name for a key. /// protected virtual string KeyTagName { get { return DefaultKeyTag; } } /// /// Gets the XML tag name for a value. /// protected virtual string ValueTagName { get { return DefaultValueTag; } } /// /// Gets the XML schema for the XML serialization. /// /// An XML schema for the serialized object. public XmlSchema GetSchema() { return null; } /// /// Deserializes the object from XML. /// /// The XML representation of the object. public void ReadXml(XmlReader reader) { var wasEmpty = reader.IsEmptyElement; reader.Read(); if (wasEmpty) { return; } try { while (reader.NodeType != XmlNodeType.EndElement) { this.ReadItem(reader); reader.MoveToContent(); } } finally { reader.ReadEndElement(); } } /// /// Serializes this instance to XML. /// /// The XML writer to serialize to. public void WriteXml(XmlWriter writer) { foreach (var keyValuePair in this) { this.WriteItem(writer, keyValuePair); } } /// /// Deserializes the dictionary item. /// /// The XML representation of the object. private void ReadItem(XmlReader reader) { reader.ReadStartElement(this.ItemTagName); try { this.Add(this.ReadKey(reader), this.ReadValue(reader)); } finally { reader.ReadEndElement(); } } /// /// Deserializes the dictionary item's key. /// /// The XML representation of the object. /// The dictionary item's key. private TKey ReadKey(XmlReader reader) { reader.ReadStartElement(this.KeyTagName); try { return (TKey)keySerializer.Deserialize(reader); } finally { reader.ReadEndElement(); } } /// /// Deserializes the dictionary item's value. /// /// The XML representation of the object. /// The dictionary item's value. private TValue ReadValue(XmlReader reader) { reader.ReadStartElement(this.ValueTagName); try { return (TValue)valueSerializer.Deserialize(reader); } finally { reader.ReadEndElement(); } } /// /// Serializes the dictionary item. /// /// The XML writer to serialize to. /// The key/value pair. private void WriteItem(XmlWriter writer, KeyValuePair keyValuePair) { writer.WriteStartElement(this.ItemTagName); try { this.WriteKey(writer, keyValuePair.Key); this.WriteValue(writer, keyValuePair.Value); } finally { writer.WriteEndElement(); } } /// /// Serializes the dictionary item's key. /// /// The XML writer to serialize to. /// The dictionary item's key. private void WriteKey(XmlWriter writer, TKey key) { writer.WriteStartElement(this.KeyTagName); try { keySerializer.Serialize(writer, key); } finally { writer.WriteEndElement(); } } /// /// Serializes the dictionary item's value. /// /// The XML writer to serialize to. /// The dictionary item's value. private void WriteValue(XmlWriter writer, TValue value) { writer.WriteStartElement(this.ValueTagName); try { valueSerializer.Serialize(writer, value); } finally { writer.WriteEndElement(); } } } }
请尝试这种替代方法:
void Main() { var source= new TestClass() { GroupTestTyped= new Dictionary { {"A", 23}, {"B", 40} } }; using (var writer = XmlWriter.Create("c:\\test1.xml")) (new XmlSerializer(typeof(TestClass))).Serialize(writer, source); } [Serializable] public class DemoElementClass { public string Key { get; set; } public int Value { get; set; } } [Serializable] public class TestClass { public TestClass() { } [XmlArray] [XmlArrayItem(ElementName = "ElementTest")] public List GroupTest { get; set; } [XmlIgnore] public Dictionary GroupTestTyped { get { return GroupTest.ToDictionary(x=> x.Key, x => x.Value); } set { GroupTest = value.Select(x => new DemoElementClass() {Key = x.Key, Value = x.Value}).ToList(); } } }
这里的xml结果:
A 23 B 40
这是基于Gildors答案的更短版本:
[XmlElement("Dictionary")] public List> XMLDictionaryProxy { get { return new List>(this.Dictionary); } set { this.Dictionary = new Dictionary(); foreach (var pair in value) this.Dictionary[pair.Key] = pair.Value; } } [XmlIgnore] public Dictionary Dictionary { get; set; }
请享用。