我正试图弄清楚如何正确行事。到目前为止,我正在使用此方法序列化对象列表:
var serializer = new System.Xml.Serialization.XmlSerializer(typeof(MyInfo));
using (var writer = new StreamWriter("SerializedValues.xml"))
{
foreach (var o in dic.Values)
serializer.Serialize(writer, o);
}
它变成了一个单独的XML文件列表,每个文件都有自己的标题,但都在一个文件中。我认为那是不对的。
然后我尝试反序列化它,它给了我以下错误:
意外的XML声明。 XML声明必须是文档中的第一个节点,并且不允许在其前面显示空白字符。第5行,第17位。
这正是下一个XML标头开始的地方。所以我猜我错了序列化。
还有一个问题来自反序列化返回单个对象的事实,这听起来已经错了,因为我期待一系列的排序。
如何正确序列化?
答案 0 :(得分:1)
序列化整个字典怎么样?
编辑:好的,如何作为KeyValuePair的列表?
var list = dic.ToList();
XmlSerializer s = new XmlSerializer(list.GetType());
using (StreamWriter file = new StreamWriter("SerializedValues.xml"))
s.Serialize(file, list);
答案 1 :(得分:0)
我设法通过在序列化之前将值转换为数组来实现这一目的:
var serializer = new System.Xml.Serialization.XmlSerializer(typeof(MyInfo[]));
using (var writer = new StreamWriter("SerializedValues.xml"))
{
serializer.Serialize(writer, dic.Values.ToArray());
}
并将其反序列化:
using (var reader = new StreamReader("SerializedValues.xml"))
{
var array = (MyInfo[])serializer.Deserialize(reader);
foreach (var v in array)
dic[v.id] = v;
}
答案 2 :(得分:0)
虽然你的解决方案适用于这个特定情况 - 因为Value也有关于Key的信息 - 我仍然会寻求更通用的解决方案。
即使Value没有关于密钥的信息,agentnega的修改后的答案也会起作用。
我最喜欢的是SerializableDictionary。因为(de)序列化没有额外的工作!取自这里: http://csharpcodewhisperer.blogspot.co.at/2013/06/namespace-xmlserializabledictionary.html
namespace XMLSerializableDictionary
{
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
[Serializable]
[XmlRoot("Dictionary")]
public class SerializableDictionary<TKey, TValue>
: Dictionary<TKey, TValue>, IXmlSerializable
{
private const string DefaultTagItem = "Item";
private const string DefaultTagKey = "Key";
private const string DefaultTagValue = "Value";
private static readonly XmlSerializer KeySerializer =
new XmlSerializer(typeof(TKey));
private static readonly XmlSerializer ValueSerializer =
new XmlSerializer(typeof(TValue));
public SerializableDictionary() : base()
{
}
protected SerializableDictionary(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
protected virtual string ItemTagName
{
get { return DefaultTagItem; }
}
protected virtual string KeyTagName
{
get { return DefaultTagKey; }
}
protected virtual string ValueTagName
{
get { return DefaultTagValue; }
}
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
bool wasEmpty = reader.IsEmptyElement;
reader.Read();
if (wasEmpty)
{
return;
}
try
{
while (reader.NodeType != XmlNodeType.EndElement)
{
reader.ReadStartElement(this.ItemTagName);
try
{
TKey tKey;
TValue tValue;
reader.ReadStartElement(this.KeyTagName);
try
{
tKey = (TKey)KeySerializer.Deserialize(reader);
}
finally
{
reader.ReadEndElement();
}
reader.ReadStartElement(this.ValueTagName);
try
{
tValue = (TValue)ValueSerializer.Deserialize(reader);
}
finally
{
reader.ReadEndElement();
}
this.Add(tKey, tValue);
}
finally
{
reader.ReadEndElement();
}
reader.MoveToContent();
}
}
finally
{
reader.ReadEndElement();
}
}
public void WriteXml(XmlWriter writer)
{
foreach (KeyValuePair<TKey, TValue> keyValuePair in this)
{
writer.WriteStartElement(this.ItemTagName);
try
{
writer.WriteStartElement(this.KeyTagName);
try
{
KeySerializer.Serialize(writer, keyValuePair.Key);
}
finally
{
writer.WriteEndElement();
}
writer.WriteStartElement(this.ValueTagName);
try
{
ValueSerializer.Serialize(writer, keyValuePair.Value);
}
finally
{
writer.WriteEndElement();
}
}
finally
{
writer.WriteEndElement();
}
}
}
}
}