xml序列化集合.docx
- 文档编号:30037911
- 上传时间:2023-08-04
- 格式:DOCX
- 页数:21
- 大小:22.63KB
xml序列化集合.docx
《xml序列化集合.docx》由会员分享,可在线阅读,更多相关《xml序列化集合.docx(21页珍藏版)》请在冰豆网上搜索。
xml序列化集合
xml序列化集合
Xml序列化是将对象中的字段和值序列化为Xml流,保存为Xml文件的格式。
反序列化是将类从Xml流中读出。
主要用到的类为:
XmlSerializer,它的主要方法有Serialize和Deserialize,用来序列化和反序列化Xml。
XmlSerializer构造函数中的参数Typetype,用来表示要进行序列化的类的类型,可以通过typeof(类名)来获取。
Serialize有两个参数Streamstream和Objecto,分别表示序列化的流和要序列化的对象。
Deserialize有一个参数Streamstream表示要反序列化的流。
可以用属性来控制Xml的序列化,XmlAttribute属性表示对象成员序列化为Xml属性,
XmlElement属性表示要将成员序列化为Xml元素,XmlArray属性应用于数组成员,数组的成员将成为Xml数组的成员。
XmlRoot属性表示要序列化为Xml的根元素。
在这些属性中都可以进一步制定元素的名称,是否为空等。
XmlRoot属性中还可以制定命名空间。
[XmlArray(ElementName="Items")]
[XmlElement(IsNullable=false)]
[XmlRoot(ElementName="PurchaseOrder",Namespace=“http:
//www.w3.org”)]
[XmlAttribute]
Xml序列化这个东西挺搞人的,当你的Class里有Hashtable这样的东西的时候,在序列化的时候,在
XmlSerializerserialize=newXmlSerializer(typeof(myClass));
这一句上会出来一个“反射类型时出错”的错误。
其实就是那个Hashtable在搞鬼,直接把上面一句换成
XmlSerializerserialize=newXmlSerializer(typeof(Hashtable));
罪魁祸首就出来了。
这次是:
“不支持类型System.Collections.Hashtable,因为它实现IDictionary”。
原来Xml序列化时对集合类还有一些比较特殊的要求。
那先来看一个可以正常序列化的集合类――Arraylist:
serialize=newXmlSerializer(typeof(ArrayList));
在序列化过程中临时生成的文件中可以发现如下的语句:
WriteStartElement(@"ArrayOfAnyType",@"");
for(intia=0;ia Write1_Object(@"anyType",@"",((System.Object)a[ia]),true,false); } WriteEndElement(); 对于集合类,在Xml序列化过程中都是要如上所述来写Xml的,显然的,对于实现了IDictionary接口的集合来讲,上面那个for循环是走不通的。 因为对于IDictionary来讲Item属性(也就是C#里的[]这个东西,也叫索引器,名字反正有点乱啦)是这样定义的: [C#] objectthis[ objectkey ]{get;set;}objectthis[ objectkey ]{get;set;} 上面是从结果上看,猜想最终序列化的时候,集合类是要以上面那样的循环方式进行序列化的,而实现了IDictionary接口的类对于那样的方式是不灵的,所以在生成临时文件的时候就不让它生成了,反正生成的DLL也是无法运行的,直接一个异常出来了。 其实在SDK上可以查到,关于Xml序列化有这么一段: XmlSerializer可以以不同方式处理实现IEnumerable或ICollection的类(条件是这些类满足某些要求)。 实现IEnumerable的类必须实现带单个参数的公共Add方法。 Add方法的参数必须与从GetEnumerator方法返回的IEnumerator.Current属性所返回的类型一致(多态)。 除实现IEnumerable外还实现ICollection的类(如CollectionBase)必须有一个取整数的公共Item索引属性(在C#中为索引器),并且它必须有一个整数类型的公共Count属性。 传递给Add方法的参数必须与从Item属性返回的类型相同或与该类型的某个基的类型相同。 对于实现ICollection的类,要序列化的值将从索引Item属性检索,而不是通过调用GetEnumerator来检索。 另外请注意,除返回另一个集合类(实现ICollection的集合类)的公共字段之外,将不序列化公共字段和属性。 无法满足上述条件的都会抛出相应的异常,而实现了IDictionary接口的类显然是无法满足的,.Net在实现的时候,一开始就先判断是不是实现了IDictionary接口,发现实现了这个接口的直接就出来了,下面什么Add方法、Item属性呀都不管了。 还有一点,就是 l类(Class这一级)――包括集合类与非集合, l非集合类 需要序列化的属性里的访问方法(不用序列化的属性例外), l在集合类里,上面提到过的Add方法,Item属性、Count属性、Current属性的访问方法等, 如果有过SecurityAttribute声明的也是无法序列化的。 不过现在写代码那个SecurityAttribute用得是甚少――这个方面的东西除了照例子依样画葫芦过一下在实践中根本是没有涉足。 要序列化Hashtable其实就只是少一个整数类型的Item属性而已,在这上面是没有什么办法了。 想到SortedList这个东西很多方面跟Hashtable差不多,不过它还能依序取得集合中的元素,只是用的不是整数类型的Item属性,而是用GetByIndex()方法。 所以就用它来偷梁换柱一下了。 //[EnvironmentPermission(SecurityAction.Assert)] publicclassMyCollection: ICollection{ privateSortedListlist=newSortedList(); publicMyCollection(){ } //[EnvironmentPermission(SecurityAction.Assert)] publicvoidAdd(Itemitem){ list.Add(item.ID,item); } publicItemthis[intindex]{ get{return(Item)list.GetByIndex(index);} } ICollection成员#regionICollection成员 publicboolIsSynchronized{ get{ returnfalse; } } publicintCount{ get{ returnlist.Count; } } [EnvironmentPermission(SecurityAction.Assert)] publicvoidCopyTo(Arrayarray,intindex){ list.CopyTo(array,index); } publicobjectSyncRoot{ get{ returnthis; } } #endregion IEnumerable成员#regionIEnumerable成员 publicIEnumeratorGetEnumerator(){ returnlist.GetEnumerator(); } #endregion } Item是自定义的一个类。 没什么具体的意义。 这样偷一下,上面的这个MyCollection类就是可以被序列化的了,然后把SortedList其他属性包一下,就基本可以当成一个SortedList使用了,说它是Hashtable也差不多吧――外表基本看不出来。 不过局限性还是有喽。 它的Add方法的参数,与Item属性的类型必须是强类型的,不能用Objcet。 用Object类型,临时文件是可以生成,serialize=newXmlSerializer(typeof(Myclass));这一句是可以通过没异常了。 但真正序列化的时候,除非是一些基本的数据类型,否则它不知道如何去把那个类型写成相应的String,写Xml文件就出错了。 附加一些冗于的资料: 1/**//// 2///序列化类。 3/// 4publicclassSerializer 5{ 6//防止被实例化。 7privateSerializer() 8{ 9 10} 11/**//// 12///静态构造函数仅在设置CanBinarySerialize值中使用一次。 13/// 14staticSerializer() 15{ 16SecurityPermissionsp=newSecurityPermission(SecurityPermissionFlag.SerializationFormatter); 17try 18{ 19sp.Demand(); 20CanBinarySerialize=true; 21} 22catch(SecurityException) 23{ 24CanBinarySerialize=false; 25} 26} 27/**//// 28///获取二进制序列化是否被使用。 29/// 30publicstaticreadonlyboolCanBinarySerialize; 31/**//// 32///将对象转化成二进制的数组。 33/// 34/// 35/// 36publicstaticbyte[]ConvertToBytes(objectobjectToConvert) 37{ 38byte[]byteArray=null; 39 40if(CanBinarySerialize) 41{ 42BinaryFormatterbinaryFormatter=newBinaryFormatter(); 43using(MemoryStreamms=newMemoryStream()) 44{ 45 46binaryFormatter.Serialize(ms,objectToConvert); 47//设置是内存存储位置为0。 48ms.Position=0; 49//读取数组。 50byteArray=newByte[ms.Length]; 51ms.Read(byteArray,0,byteArray.Length); 52ms.Close(); 53} 54} 55returnbyteArray; 56} 57/**//// 58///将对象以二进制形式存储到硬盘中。 59/// 60/// 61/// 62/// 63publicstaticboolSaveAsBinary(objectobjectToSave,stringpath) 64{ 65if(objectToSave! =null&&CanBinarySerialize) 66{ 67byte[]ba=ConvertToBytes(objectToSave); 68if(ba! =null) 69{ 70using(FileStreamfs=newFileStream(path,FileMode.OpenOrCreate,FileAccess.Write)) 71{ 72using(BinaryWriterbw=newBinaryWriter(fs)) 73{ 74bw.Write(ba); 75returntrue; 76} 77} 78} 79} 80returnfalse; 81} 82/**//// 83///将对象转化为Xml格式文件,该对象必须用[Serialize]标记,否则将抛出错误。 84/// 85/// 86/// 87publicstaticstringConvertToString(objectobjectToConvert) 88{ 89stringXml=null; 90 91if(objectToConvert! =null) 92{ 93//获取当前序列化对象。 94Typet=objectToConvert.GetType(); 95 96XmlSerializerser=newXmlSerializer(t); 97//将序列化的结果保存到Xml中。 98using(StringWriterwriter=newStringWriter(CultureInfo.InvariantCulture)) 99{ 100ser.Serialize(writer,objectToConvert); 101Xml=writer.ToString(); 102writer.Close(); 103} 104} 105 106returnXml; 107} 108/**//// 109///将对象序列化后以Xml格式存储于文件中。 110/// 111/// 112/// 113publicstaticvoidSaveAsXml(objectobjectToConvert,stringpath) 114{ 115if(objectToConvert! =null) 116{ 117Typet=objectToConvert.GetType(); 118 119XmlSerializerser=newXmlSerializer(t); 120 121using(StreamWriterwriter=newStreamWriter(path)) 122{ 123ser.Serialize(writer,objectToConvert); 124writer.Close(); 125} 126} 127 128} 129/**//// 130///将一个二进制的数组转化为对象,必须通过类型转化自己想得到的相应对象。 如果数组为空则返回空。 131/// 132/// 133/// 134publicstaticobjectConvertToObject(byte[]byteArray) 135{ 136objectconvertedObject=null; 137if(CanBinarySerialize&&byteArray! =null&&byteArray.Length>0) 138{ 139BinaryFormatterbinaryFormatter=newBinaryFormatter(); 140using(MemoryStreamms=newMemoryStream()) 141{ 142ms.Write(byteArray,0,byteArray.Length); 143 144ms.Position=0; 145 146if(byteArray.Length>4) 147convertedObject=binaryFormatter.Deserialize(ms); 148 149ms.Close(); 150} 151} 152returnconvertedObject; 153} 154/**//// 155///将文件的数据转化为对象。 156/// 157/// 158/// 159/// 160publicstaticobjectConvertFileToObject(stringpath,TypeobjectType) 161{ 162objectconvertedObject=null; 163 164if(path! =null&&path.Length>0) 165{ 166using(FileStreamfs=newFileStream(path,FileMode.Open,FileAccess.Read)) 167{ 168XmlSerializerser=newXmlSerializer(objectType); 169convertedObject=ser.Deserialize(fs); 170fs.Close(); 171} 172} 173returnconvertedObject; 174} 175/**//// 176///将Xml格式的字符串反序列化为实例对象。 177/// 178/// 179/// 180/// 181publicstaticobjectConvertToObject(stringXml,TypeobjectType) 182{ 183objectconvertedObject=null; 184 185if(! WebHelper.IsNullOrEmpty(Xml)) 186{ 187using(StringReaderreader=newStringReader(Xml)) 188{ 189XmlSerializerser=newXmlSerializer(objectType); 190convertedObject=ser.Deserialize(reader); 191reader.Close(); 192} 193} 194returnconvertedObject; 195} 196/**//// 197///将Xml节点反序列化为实例对象。 198/// 199/// 200/// 201/// 202publicstaticobjectConvertToObject(XmlNodenode,TypeobjectType) 203{ 204objectconvertedObject=null; 205 206if(node! =null) 207{ 208using(StringReaderreader=newStringReader(node.OuterXml)) 209{ 210 211XmlSerializerser=newXmlSerializer(objectType); 212 213convertedObject=ser.Deserialize(reader); 214 215reader.Close(); 216} 217} 218returnconvertedObject; 219} 220/**//// 221///加载一个二进制文件并将其转化为实例对象。 222/// 223/// 224/// 225publicstaticobjectLoadBinaryFile(stringp
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- xml 序列 集合
![提示](https://static.bdocx.com/images/bang_tan.gif)