這篇隨筆對應的.Net命名空間是System.Xml.Serialization;文中的示例代碼需要引用這個命名空間。
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進行反序列化,如下代碼
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));//反序列化,并將反序列化結果值賦給變量iint 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。
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節點名。
如下代碼示例:
/*玉開技術博客 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; }}
}
以上代碼將輸出:
<?xml version="1.0" encoding="gb2312"?>
<cats xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://ww
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的相關隨筆: