1
2
3
4
5
6
7
8
9
10
11
12
|
class
Program { static
void Main( string [] args) { int
i = 10; //聲明Xml序列化對象實例serializer XmlSerializer serializer =
new XmlSerializer( typeof ( int )); //執行序列化並將序列化結果輸出到控制檯 serializer.Serialize(Console.Out, i); Console.Read(); } } |
上面代碼對int i進行了序列化,並將序列化的結果輸出到了控制檯,輸出結果如下
<? xml
version = "1.0"
encoding = "gb2312" ?> < int >10</ int > |
可以將上述序列化的xml進行反序列化,如下代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
static
void Main( string [] args) { using
(StringReader rdr = new
StringReader( @"<?xml version=""1.0"" encoding=""gb2312""?> <int>10</int>" )) { //聲明序列化對象實例serializer
XmlSerializer serializer =
new XmlSerializer( typeof ( int )); //反序列化,並將反序列化結果值賦給變量i int
i = ( int )serializer.Deserialize(rdr); //輸出反序列化結果 Console.WriteLine( "i = "
+ i); Console.Read(); } } |
以上代碼用最簡單的方式說明了xml序列化和反序列化的過程,.Net系統類庫爲我們做了大量的工作,序列化和反序列化都非常簡單。但是在現實中業務需求往往比較複雜,不可能只簡單的序列化一個int變量,顯示中我們需要對複雜類型進行可控制的序列化。
自定義對象的Xml序列化:
System.Xml.Serialization命名空間中有一系列的特性類,用來控制複雜類型序列化的控制。例如XmlElementAttribute、XmlAttributeAttribute、XmlArrayAttribute、XmlArrayItemAttribute、XmlRootAttribute等等。
看一個小例子,有一個自定義類Cat,Cat類有三個屬性分別爲Color,Saying,Speed。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
namespace
UseXmlSerialization { class
Program { static
void Main( string [] args) { //聲明一個貓咪對象 var c =
new Cat { Color =
"White" , Speed = 10, Saying =
"White or black, so long as the cat can catch mice, it is a good cat"
}; //序列化這個對象 XmlSerializer serializer =
new XmlSerializer( typeof (Cat)); //將對象序列化輸出到控制檯 serializer.Serialize(Console.Out, c); Console.Read(); } } [XmlRoot( "cat" )] public
class Cat { //定義Color屬性的序列化爲cat節點的屬性 [XmlAttribute( "color" )] public
string Color {
get ; set ; } //要求不序列化Speed屬性 [XmlIgnore] public
int Speed {
get ; set ; } //設置Saying屬性序列化爲Xml子元素 [XmlElement( "saying" )] public
string Saying {
get ; set ; } } } |
可以使用XmlElement指定屬性序列化爲子節點(默認情況會序列化爲子節點);或者使用XmlAttribute特性制定屬性序列化爲Xml節點的屬性;還可以通過XmlIgnore特性修飾要求序列化程序不序列化修飾屬性。
對象數組的Xml序列化:
數組的Xml序列化需要使用XmlArrayAttribute和XmlArrayItemAttribute;XmlArrayAttribute指定數組元素的Xml節點名,XmlArrayItemAttribute指定數組元素的Xml節點名。
如下代碼示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
/*玉開技術博客
http://www.cnblogs.com/yukaizhao */ using
System; using
System.Collections.Generic; using
System.Linq; using
System.Text; using
System.Xml.Serialization; namespace
UseXmlSerialization { class
Program { static
void Main( string [] args) { //聲明一個貓咪對象 var cWhite =
new Cat { Color =
"White" , Speed = 10, Saying =
"White or black, so long as the cat can catch mice, it is a good cat"
}; var cBlack =
new Cat { Color =
"Black" , Speed = 10, Saying =
"White or black, so long as the cat can catch mice, it is a good cat"
}; CatCollection cc =
new CatCollection { Cats =
new Cat[] { cWhite,cBlack} }; //序列化這個對象 XmlSerializer serializer =
new XmlSerializer( typeof (CatCollection)); //將對象序列化輸出到控制檯 serializer.Serialize(Console.Out, cc); Console.Read(); } } [XmlRoot( "cats" )] public
class CatCollection { [XmlArray( "items" ),XmlArrayItem( "item" )] public
Cat[] Cats { get ;
set ; } } [XmlRoot( "cat" )] public
class Cat { //定義Color屬性的序列化爲cat節點的屬性 [XmlAttribute( "color" )] public
string Color {
get ; set ; } //要求不序列化Speed屬性 [XmlIgnore] public
int Speed {
get ; set ; } //設置Saying屬性序列化爲Xml子元素 [XmlElement( "saying" )] public
string Saying {
get ; set ; } } } |
以上代碼將輸出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<? xml
version = "1.0"
encoding = "gb2312" ?> w.w3.org/2001/XMLSchema"> < items > < item
color = "White" > < saying >White or black, so long as the cat can catch mice, it is a good cat</ saying > </ item > < item
color = "Black" > < saying >White or black, so long as the cat can catch mice, it is a good cat</ saying > </ item > </ items > </ cats > |
XmlSerializer內存泄漏問題:
多謝chenlulouis,仔細看了下msdn,確實存在泄漏的情況,msdn說明如下:
動態生成的程序集
爲了提高性能,XML 序列化基礎結構將動態生成程序集,以序列化和反序列化指定類型。此基礎結構將查找並重複使用這些程序集。此行爲僅在使用以下構造函數時發生:
XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type, String)
如果使用任何其他構造函數,則會生成同一程序集的多個版本,且絕不會被卸載,這將導致內存泄漏和性能降低。最簡單的解決方案是使用先前提到的兩個構造函數的其中一個。否則,必須在 Hashtable 中緩存程序集,如以下示例中所示。
也就是說我們在使用XmlSerializer序列化,初始化XmlSerializer對象時最好使用下面兩個構造函數否則會引起內存泄漏。
XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type, String)
C#處理Xml的相關隨筆: