xml序列化集合.docx

上传人:b****5 文档编号:30037911 上传时间:2023-08-04 格式:DOCX 页数:21 大小:22.63KB
下载 相关 举报
xml序列化集合.docx_第1页
第1页 / 共21页
xml序列化集合.docx_第2页
第2页 / 共21页
xml序列化集合.docx_第3页
第3页 / 共21页
xml序列化集合.docx_第4页
第4页 / 共21页
xml序列化集合.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

xml序列化集合.docx

《xml序列化集合.docx》由会员分享,可在线阅读,更多相关《xml序列化集合.docx(21页珍藏版)》请在冰豆网上搜索。

xml序列化集合.docx

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///返回转化后的数组,如果CanBinarySerialize为false则返回null。

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///如果存储成功则返回true,否则返回false。

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///返回Xml文本,如果对象为空则返回null。

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///Xml格式字符串。

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///用于反序列化的Xml节点。

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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1