使用XmlSerializer类将对象序列化为Xml格式保存_支持泛型的Dicti
在一个特殊应用中,我们需要将内存中的一个对象持久化,而这个对象是来自一个模板类实例化出来的,不能保存到数据库中,数据库中只存有此对象的模板. 由于使用到泛型的Dictionary,而XmlSerializer却不支持默认的泛型的Dictionary,为此我找了些资料,并在此文中以三种不同的方式实现. 本文中约定: 方案1: 不序列化泛型的Dictionary 方案2: 定义支持泛型的Dictionary 方案3: 让每个类实现IXmlSerializable接口 薪酬模板PayTemplate,它通过Dictionary<int,PayItemTemplate>维持着多个薪酬栏目模板PayItemTemplate. 而一个PayItemTemplate通过Dictionary<int,PayItemTemplate>记录着那些使用过它的PayItemTemplate. 所以,PayTemplate与PayItemTemplate是一对多关联; PayItemTemplate是一对多的自关联. 方案1,2,3中的类关联都相似,这里就不重复了. 详细差别可在本文末尾下载源代码查看. 46 [XmlIgnore]//带有XmlIgnore,表示序列化时不序列化此属性 47 publicDictionary<int,PayItemTemplate> PayItemTemplateDic 48 { 49 get{returnpayItemTemplates; } 50 set{ payItemTemplates =value; } 51 } 好了,既然让泛型的Dictionary不被序列化了,而我们的需求中又需要将泛型的Dictionary中的对象序列化到Xml中保存,那怎么办呢?这里的办法就是加多一个额外的PayItemTemplate[]数组字段,代码实现如下: 53 ///<summary> 54 ///用于序列化PayItemTemplate集合 55 ///</summary> 56 publicPayItemTemplate[] PayItemTemplates 57 { 58 get 59 { 60 List<PayItemTemplate> list =newList<PayItemTemplate>(payItemTemplates.Count); 61 foreach(KeyValuePair<int,PayItemTemplate> pitinpayItemTemplates) 62 { 63 list.Add(pit.Value); 64 } 65 66 returnlist.ToArray(); 67 } 68 set 69 { 70 payItemTemplates =newDictionary<int,PayItemTemplate>(); 71 foreach(PayItemTemplatepitinvalue) 72 { 73 payItemTemplates.Add(pit.Id,pit); 74 } 75 } 76 } <?xmlversion="1.0"encoding="utf-8"?> <PayTemplatexmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Id>100</Id> <Name>薪酬模版Test</Name> <StartDate>2007-08-16T19:10:43.640625+08:00</StartDate> <PayItemTemplates> <PayItemTemplate> <numbericalCategory>Calculational</numbericalCategory> <NumbericalCategory>Calculational</NumbericalCategory> <Id>10000</Id> <Name>薪酬模板栏目1</Name> <PayItemTemplateRelieds> <PayItemTemplate> <numbericalCategory>Calculational</numbericalCategory> <NumbericalCategory>Calculational</NumbericalCategory> <Id>20000</Id> <Name>薪酬模板栏目2</Name> <PayItemTemplateRelieds/> <Enabled>true</Enabled> <Expression>Expression2</Expression> </PayItemTemplate> </PayItemTemplateRelieds> <Enabled>true</Enabled> <Expression>Expression</Expression> </PayItemTemplate> <PayItemTemplate> <numbericalCategory>Calculational</numbericalCategory> <NumbericalCategory>Calculational</NumbericalCategory> <Id>20000</Id> <Name>薪酬模板栏目2</Name> <PayItemTemplateRelieds/> <Enabled>true</Enabled> <Expression>Expression2</Expression> </PayItemTemplate> </PayItemTemplates> <WorkFlowCategory>Simple</WorkFlowCategory> </PayTemplate> 方案1优缺点: 不用定义额外的对象,但出现多余的字段(多余是因为此字段只是为了序列化而出现的). 25 ///<summary> 26 ///反序列化 27 ///</summary> 28 ///<param name="reader"></param> 29 publicvoidReadXml(XmlReaderreader) 30 { 31 XmlSerializerkeySerializer =newXmlSerializer(typeof(TKey)); 32 XmlSerializervalueSerializer =newXmlSerializer(typeof(TValue)); 33 if(reader.IsEmptyElement || !reader.Read()) 34 { 35 return; 36 } 37 38 while(reader.NodeType !=XmlNodeType.EndElement) 39 { 40 reader.ReadStartElement("item"); 41 42 reader.ReadStartElement("key"); 43 TKey key = (TKey)keySerializer.Deserialize(reader); 44 reader.ReadEndElement(); 45 46 reader.ReadStartElement("value"); 47 TValue value = (TValue)valueSerializer.Deserialize(reader); 48 reader.ReadEndElement(); 49 50 reader.ReadEndElement(); 51 reader.MoveToContent(); 52 53 this.Add(key,value); 54 } 55 reader.ReadEndElement(); 56 } 57 58 ///<summary> 59 ///序列化 60 ///</summary> 61 ///<param name="writer"></param> 62 publicvoidWriteXml(XmlWriterwriter) 63 { 64 XmlSerializerkeySerializer =newXmlSerializer(typeof(TKey)); 65 XmlSerializervalueSerializer =newXmlSerializer(typeof(TValue)); 66 67 foreach(TKey keyinthis.Keys) 68 { 69 writer.WriteStartElement("item"); 70 71 writer.WriteStartElement("key"); 72 keySerializer.Serialize(writer,key); 73 writer.WriteEndElement(); 74 75 writer.WriteStartElement("value"); 76 valueSerializer.Serialize(writer,this[key]); 77 writer.WriteEndElement(); 78 79 writer.WriteEndElement(); 80 } 81 }
<?xmlversion="1.0"encoding="utf-8"?> <PayTemplateV2xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Id>100</Id> <Name>薪酬模版Test</Name> <StartDate>2007-08-16T19:08:45.0625+08:00</StartDate> <PayItemTemplates> <item> <key> <int>10000</int> </key> <value> <PayItemTemplateV2> <numbericalCategory>Calculational</numbericalCategory> <NumbericalCategory>Calculational</NumbericalCategory> <Id>10000</Id> <Name>薪酬模板栏目1</Name> <PayItemTemplateReliedList> <item> <key> <int>20000</int> </key> <value> <PayItemTemplateV2> <numbericalCategory>Calculational</numbericalCategory> <NumbericalCategory>Calculational</NumbericalCategory> <Id>20000</Id> <Name>薪酬模板栏目2</Name> <PayItemTemplateReliedList/> <Enabled>true</Enabled> <Expression>Expression2</Expression> </PayItemTemplateV2> </value> </item> </PayItemTemplateReliedList> <Enabled>true</Enabled> <Expression>Expression</Expression> </PayItemTemplateV2> </value> </item> <item> <key> <int>20000</int> </key> <value> <PayItemTemplateV2> <numbericalCategory>Calculational</numbericalCategory> <NumbericalCategory>Calculational</NumbericalCategory> <Id>20000</Id> <Name>薪酬模板栏目2</Name> <PayItemTemplateReliedList/> <Enabled>true</Enabled> <Expression>Expression2</Expression> </PayItemTemplateV2> </value> </item> </PayItemTemplates> <WorkFlowCategory>Simple</WorkFlowCategory> </PayTemplateV2> 4. 方案3: 让每个类实现IXmlSerializable接口 <?xmlversion="1.0"encoding="utf-8"?> <PayTemplateV3> <Id>100</Id> <Name>薪酬模版Test</Name> <StartDate>2007年8月17日</StartDate> <WorkFlowCategory>Simple</WorkFlowCategory> <PayItemTemplates> <PayItemTemplateV3> <Id>10000</Id> <Name>薪酬模板栏目1</Name> <Expression>Expression</Expression> <Enabled>True</Enabled> <NumbericalCategory>Calculational</NumbericalCategory> <PayItemTemplateReliedList> <PayItemTemplateV3> <Id>20000</Id> <Name>薪酬模板栏目2</Name> <Expression>Expression2</Expression> <Enabled>True</Enabled> <NumbericalCategory>Calculational</NumbericalCategory> <PayItemTemplateReliedList/> </PayItemTemplateV3> </PayItemTemplateReliedList> </PayItemTemplateV3> <PayItemTemplateV3> <Id>20000</Id> <Name>薪酬模板栏目2</Name> <Expression>Expression2</Expression> <Enabled>True</Enabled> <NumbericalCategory>Calculational</NumbericalCategory> <PayItemTemplateReliedList/> </PayItemTemplateV3> </PayItemTemplates> </PayTemplateV3> 完. :) 希望这对你有帮助. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |