c# - serialize - Cómo XML-serializar un diccionario
serialize entity to xml (4)
Aquí hay una versión aún más corta basada en la respuesta de Gildors:
[XmlElement("Dictionary")]
public List<KeyValuePair<string, string>> XMLDictionaryProxy
{
get
{
return new List<KeyValuePair<string, string>>(this.Dictionary);
}
set
{
this.Dictionary = new Dictionary<string, string>();
foreach (var pair in value)
this.Dictionary[pair.Key] = pair.Value;
}
}
[XmlIgnore]
public Dictionary<string, string> Dictionary
{
get; set;
}
Disfrutar.
He podido serializar un IEnumerable de esta manera:
[XmlArray("TRANSACTIONS")]
[XmlArrayItem("TRANSACTION", typeof(Record))]
public IEnumerable<BudgetRecord> Records
{
get
{
foreach(Record br in _budget)
{
yield return br;
}
}
}
Sin embargo, me di cuenta de que ahora necesito un diccionario que contenga una colección Dictionary<string, RecordCollection>
(RecordCollection implementa IEnumerable).
¿Cómo puedo lograr eso?
Echa un vistazo a la siguiente entrada de blog
-
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
y este (no en inglés, pero el código es útil)
He usado el siguiente por un tiempo. Originalmente viene de here .
namespace SerializeDictionary
{
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
/// <summary>
/// Represents an XML serializable collection of keys and values.
/// </summary>
/// <typeparam name="TKey">The type of the keys in the dictionary.</typeparam>
/// <typeparam name="TValue">The type of the values in the dictionary.</typeparam>
[Serializable]
[XmlRoot("dictionary")]
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
{
/// <summary>
/// The default XML tag name for an item.
/// </summary>
private const string DefaultItemTag = "item";
/// <summary>
/// The default XML tag name for a key.
/// </summary>
private const string DefaultKeyTag = "key";
/// <summary>
/// The default XML tag name for a value.
/// </summary>
private const string DefaultValueTag = "value";
/// <summary>
/// The XML serializer for the key type.
/// </summary>
private static readonly XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
/// <summary>
/// The XML serializer for the value type.
/// </summary>
private static readonly XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
/// <summary>
/// Initializes a new instance of the
/// <see cref="SerializableDictionary<TKey, TValue>"/> class.
/// </summary>
public SerializableDictionary()
{
}
/// <summary>
/// Initializes a new instance of the
/// <see cref="SerializableDictionary<TKey, TValue>"/> class.
/// </summary>
/// <param name="info">A
/// <see cref="T:System.Runtime.Serialization.SerializationInfo"/> object
/// containing the information required to serialize the
/// <see cref="T:System.Collections.Generic.Dictionary`2"/>.
/// </param>
/// <param name="context">A
/// <see cref="T:System.Runtime.Serialization.StreamingContext"/> structure
/// containing the source and destination of the serialized stream
/// associated with the
/// <see cref="T:System.Collections.Generic.Dictionary`2"/>.
/// </param>
protected SerializableDictionary(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
/// <summary>
/// Gets the XML tag name for an item.
/// </summary>
protected virtual string ItemTagName
{
get
{
return DefaultItemTag;
}
}
/// <summary>
/// Gets the XML tag name for a key.
/// </summary>
protected virtual string KeyTagName
{
get
{
return DefaultKeyTag;
}
}
/// <summary>
/// Gets the XML tag name for a value.
/// </summary>
protected virtual string ValueTagName
{
get
{
return DefaultValueTag;
}
}
/// <summary>
/// Gets the XML schema for the XML serialization.
/// </summary>
/// <returns>An XML schema for the serialized object.</returns>
public XmlSchema GetSchema()
{
return null;
}
/// <summary>
/// Deserializes the object from XML.
/// </summary>
/// <param name="reader">The XML representation of the object.</param>
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();
}
}
/// <summary>
/// Serializes this instance to XML.
/// </summary>
/// <param name="writer">The XML writer to serialize to.</param>
public void WriteXml(XmlWriter writer)
{
foreach (var keyValuePair in this)
{
this.WriteItem(writer, keyValuePair);
}
}
/// <summary>
/// Deserializes the dictionary item.
/// </summary>
/// <param name="reader">The XML representation of the object.</param>
private void ReadItem(XmlReader reader)
{
reader.ReadStartElement(this.ItemTagName);
try
{
this.Add(this.ReadKey(reader), this.ReadValue(reader));
}
finally
{
reader.ReadEndElement();
}
}
/// <summary>
/// Deserializes the dictionary item''s key.
/// </summary>
/// <param name="reader">The XML representation of the object.</param>
/// <returns>The dictionary item''s key.</returns>
private TKey ReadKey(XmlReader reader)
{
reader.ReadStartElement(this.KeyTagName);
try
{
return (TKey)keySerializer.Deserialize(reader);
}
finally
{
reader.ReadEndElement();
}
}
/// <summary>
/// Deserializes the dictionary item''s value.
/// </summary>
/// <param name="reader">The XML representation of the object.</param>
/// <returns>The dictionary item''s value.</returns>
private TValue ReadValue(XmlReader reader)
{
reader.ReadStartElement(this.ValueTagName);
try
{
return (TValue)valueSerializer.Deserialize(reader);
}
finally
{
reader.ReadEndElement();
}
}
/// <summary>
/// Serializes the dictionary item.
/// </summary>
/// <param name="writer">The XML writer to serialize to.</param>
/// <param name="keyValuePair">The key/value pair.</param>
private void WriteItem(XmlWriter writer, KeyValuePair<TKey, TValue> keyValuePair)
{
writer.WriteStartElement(this.ItemTagName);
try
{
this.WriteKey(writer, keyValuePair.Key);
this.WriteValue(writer, keyValuePair.Value);
}
finally
{
writer.WriteEndElement();
}
}
/// <summary>
/// Serializes the dictionary item''s key.
/// </summary>
/// <param name="writer">The XML writer to serialize to.</param>
/// <param name="key">The dictionary item''s key.</param>
private void WriteKey(XmlWriter writer, TKey key)
{
writer.WriteStartElement(this.KeyTagName);
try
{
keySerializer.Serialize(writer, key);
}
finally
{
writer.WriteEndElement();
}
}
/// <summary>
/// Serializes the dictionary item''s value.
/// </summary>
/// <param name="writer">The XML writer to serialize to.</param>
/// <param name="value">The dictionary item''s value.</param>
private void WriteValue(XmlWriter writer, TValue value)
{
writer.WriteStartElement(this.ValueTagName);
try
{
valueSerializer.Serialize(writer, value);
}
finally
{
writer.WriteEndElement();
}
}
}
}
Por favor intente esta alternativa fácil
void Main()
{
var source=
new TestClass()
{
GroupTestTyped=
new Dictionary<string, int> { {"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<DemoElementClass> GroupTest { get; set; }
[XmlIgnore]
public Dictionary<string, int> 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(); }
}
}
Aquí el resultado xml:
<?xml version="1.0" encoding="utf-8"?>
<TestClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<GroupTest>
<ElementTest>
<Key>A</Key>
<Value>23</Value>
</ElementTest>
<ElementTest>
<Key>B</Key>
<Value>40</Value>
</ElementTest>
</GroupTest>
</TestClass>