无法使用XmlSerializer读取XML内容
我在课堂上得到了这个:
namespace MSAToolsLibrary.PublisherEntry { [XmlRoot(ElementName = "PublisherDatabase", Namespace = "http://www.publictalksoftware.co.uk/msa")] public class PublisherData { public PublisherData() { //_Publishers = new List(); _PublishersDictionary = new Dictionary(); } public List Publishers { get { return _PublishersDictionary.Select(x => x.Value).ToList(); } set { _PublishersDictionary = value.ToDictionary(x => x.Name, x => x); } } private Dictionary _PublishersDictionary; [XmlIgnore] public Dictionary PublisherDictionary { get { return _PublishersDictionary; } } public void AddPublisher(String strName, String strNotes, Gender eGender, Appointed eAppointedAs, Serving eServingAs, bool bUseForDemonstrations, bool bAvailableMidweek, bool bAvailableWeekend, DateTime[] listDatesNotAvailable) { Publisher _Publisher = new Publisher() { Name = strName, Notes = strNotes, Gender = eGender, AppointedAs = eAppointedAs, ServingAs = eServingAs, }; _Publisher.Assignments.UseForDemonstrations = bUseForDemonstrations; _Publisher.Availability.Midweek = bAvailableMidweek; _Publisher.Availability.Weekend = bAvailableWeekend; _Publisher.Availability.DatesNotAvailable = new List(listDatesNotAvailable); //_Publishers.Add(_Publisher); _PublishersDictionary.Add(strName, _Publisher); } } }
现在,当我将数据保存到XML时,一切正常。
但是当我读到时:
public void ReadPublisherData(out Int64 iResult) { _PublisherData.Publishers.Clear(); // Reset iResult = MakeResult(true); try { XmlSerializer x = new XmlSerializer(_PublisherData.GetType()); using (StreamReader reader = new StreamReader(_strPathXML)) { _PublisherData = (PublisherData)x.Deserialize(reader); iResult = _PublisherData.PublisherDictionary.Count; } } catch { iResult = MakeResult(false); } }
不起作用。 我在列表或字典中没有发布者。
我究竟做错了什么?
更新
如果我更改PublisherData
声明,使其具有所需的后退字段:
public PublisherData() { _Publishers = new List(); _PublishersDictionary = new Dictionary(); } public List Publishers { get => _Publishers; set => _Publishers = value; } private List _Publishers;
然后这会导致数据正确序列化,我得到了MFC应用程序的预期。 但是现在我的PublisherDictionary
正在悬挂。 所以我添加了一个function:
public void BuildPublisherDictionary() { _PublishersDictionary = _Publishers.ToDictionary(x => x.Name, x => x); }
并调整了读取例程:
public void ReadPublisherData(out Int64 iResult) { iResult = MakeResult(true); try { _PublisherData.Publishers.Clear(); // Reset XmlSerializer x = new XmlSerializer(_PublisherData.GetType()); using (StreamReader reader = new StreamReader(_strPathXML)) { _PublisherData = (PublisherData)x.Deserialize(reader); _PublisherData.BuildPublisherDictionary(); iResult = _PublisherData.PublisherDictionary.Count; } } catch { iResult = MakeResult(false); } }
有用。 但我不知道这是否是最简单的方法。 我上面的问题是列表/字典现在彼此分离。 因此,如果我将一个发布者添加到字典中,它现在将不在列表中。
更新2
目前,在读取XML后,如果我添加或删除发布者,我将其应用于列表和字典。 除非有更简单的方法。
序列化程序只调用List的getter,然后为它找到的每个元素调用Add
,为它提供从该元素反序列化的类型的实例。
如果您的要求是同时拥有列表和字典,则必须提供执行此类型的实现并实现适用的接口。
以下ListDict使用List和Dictionary作为其后备存储,同时实现在(de)序列化中使用的IList。
public class ListDict:IList { public Dictionary dict = new Dictionary(); public List list = new List (); Func KeyFunc; // takes an Function that returns a key for T public ListDict(Func keyfunc) { KeyFunc = keyfunc; } // called by the serializer public void Add(T value) { Add( KeyFunc(value), value); } // fill both List and Dictionary public void Add(K key, T value) { list.Add(value); dict.Add( key , value); } // left out other required methods from IList }
现在,您的PublisherData类将更改如下以利用上面的类:
[XmlRoot(ElementName = "PublisherDatabase", Namespace = "http://www.publictalksoftware.co.uk/msa")] public class PublisherData { private ListDict _PublishersDictionary; public PublisherData() { // provide the function to generate a key for a Publisher _PublishersDictionary = new ListDict( (p) => p.Name ); } [XmlElement] public ListDict Publishers { get { return _PublishersDictionary; } } [XmlIgnore] public Dictionary PublisherDictionary { get {return _PublishersDictionary.dict; } } }
使用上面的类在反序列化后直接给我一个填充列表和Dictionary。 您必须确保在ListDict中保持后备存储同步。 也许你可以没有它,但这取决于你的确切用例。