微軟已經意識到串行化資料的重要性,因此在.NET框架中包含了命名空間System.Runtime.Serialization和System.Xml.Serialization以提供串行化功能,為用戶自己編寫串行化方法提供了一個框架。 System.Xml.Serialization命名空間提供了將一個物件串列化為XML格式的基本方法。下面我們來看看如何使用這種方法。
XML的魅力
串行化XML是指為了方便儲存或傳輸,把一個物件的公共的域和屬性保存為一種串行格式(這裡是XML格式)的過程。非串行化則是使用串行的狀態資訊將物件從串行XML狀態還原成原始狀態的過程。因此,可以把串列化看作是將物件的狀態保存到流或緩衝區中的一種方法。
串行化的目的是資料儲存和資料轉換。資料儲存指的是使用者會話時保存資料。當應用程式關閉時,資料被保存(串行化),而當使用者回來時,資料又被重新載入(非串行化)。資料轉換指將資料變換成能被另一個系統辨識的格式。使用串列化和XML,可以很方便的進行資料轉換。
物件中的資料可以是類別、方法、屬性、私有類型、數組,在System.Xml.XmlElement或System.Xml.XmlAttribute物件中,它甚至可以是內嵌的XML。
System.Xml.Serialization命名空間中的關鍵類別是XmlSerializer。當然在該命名空間中也包括有關XML其他方面以及SOAP相關的其他類,不過我們的重點是XmlSerializer類。
XmlSerializer
XmlSerializer類別提供了把物件串列化為XML檔及把XML文檔非串列化為物件的方法。它還能讓使用者指定物件如何轉換為XML。可以把將被串列化的物件的型別當作類別建構函式的參數。下面的C# 程式碼說明了建構函式的用法。
XmlSerializer ser = new XmlSerializer(typeof(objectToSerialize));
下面是等價的VB.NET程式碼:
Dim ser As New XmlSerializer(GetType(objectToSerialize))
實際的串行化過程在XmlSerializer類別的Serialize方法中實現。此方法允許在串列化過程中呼叫TextWriter、Stream和XmlWriter物件。下面的範例程式碼說明如何呼叫該方法。在本例中一個物件被串列化保存到本機磁碟的一個檔案當中。例子中首先是類別聲明,後面緊接著是串行化原始碼。
using System;
namespace BuilderSerialization {
public class Address {
public Address() {}
public string Address1;
public string Address2;
public string City;
public string State;
public string Zip;
public string Country;
} }
using System;
namespace BuilderSerialization {
public class Author {
public Author() { }
public string FirstName;
public string MiddleName;
public string LastName;
public string Title;
public string Gender;
public Address AddressObject;
} }
namespace BuilderSerialization {
public class Book {
public Book() { }
public string Title;
public Author AuthorObject;
public string ISBN;
public double RetailPrice;
public string Publisher;
}}
using System;
using System.Xml.Serialization;
using System.IO;
namespace BuilderSerialization {
class TestClass {
static void Main(string[] args) {
Book BookObject = new Book();
XmlSerializer ser = new XmlSerializer(typeof(Book));
TextWriter writer = new StreamWriter("booktest.xml");
BookObject.Title = "Practical LotusScript";
BookObject.ISBN = "1884777767 ";
BookObject.Publisher = "Manning Publications";
BookObject.RetailPrice = 43.95;
BookObject.AuthorObject = new Author();
BookObject.AuthorObject.FirstName = "Tony";
BookObject.AuthorObject.LastName = "Patton";
BookObject.AuthorObject.Gender = "Male";
BookObject.AuthorObject.AddressObject = new Address();
BookObject.AuthorObject.AddressObject.Address1 = "1 Main Street";
BookObject.AuthorObject.AddressObject.City = "Anywhere";
BookObject.AuthorObject.AddressObject.State = "KY";
BookObject.AuthorObject.AddressObject.Zip = "40000";
BookObject.AuthorObject.AddressObject.Country = "USA";
ser.Serialize(writer, BookObject);
writer.Close();
} } }
上面的程式碼把三個物件變成一個對象,因此在串列化過程中產生一個XML檔。以下是範例程式產生的XML文件:
xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance ">
注意串列化過程也能處理物件資料的嵌套。資料被轉換成可識別的格式,方便了資料重載(非串列化)以及向另一個系統的資料傳輸。在資料傳輸過程時,接收方系統需要知道XML檔案的格式(如果預先不知道的話)。因此需要提供一個XML schema檔。 .NET框架中的XSD.exe工具可以為串列化XML產生一個schema檔案。
下面是用VB.NET寫的範例程式碼:
Public Class Address
Public Address1 As String
Public Address2 As String
Public City As String
Public State As String
Public Zip As String
Public Country As String
End Class
Public Class Author
Public FirstName As String
Public MiddleName As String
Public LastName As String
Public Title As String
Public Gender As String
Public AddressObject As Address
End Class
Public Class Book
Public AuthorObject As Author
Public Title As String
Public ISBN As String
Public RetailPrice As Double
Public Publisher As String
End Class
Imports System.Xml.Serialization
Imports System.IO
Module Module1
Sub Main()
Dim BookObject As New Book
Dim ser As New XmlSerializer(GetType(Book))
Dim writer As New StreamWriter("booktest.xml")
With BookObject
.Title = "Practical LotusScript"
.ISBN = "1884777767 "
.Publisher = "Manning Publications"
.RetailPrice = 43.95
.AuthorObject = New Author
.AuthorObject.FirstName = "Tony"
.AuthorObject.LastName = "Patton"
.AuthorObject.Gender = "Male"
.AuthorObject.AddressObject = New Address
.AuthorObject.AddressObject.Address1 = "1 Main Street"
.AuthorObject.AddressObject.City = "Anywhere"
.AuthorObject.AddressObject.State = "KY"
.AuthorObject.AddressObject.Zip = "40000"
.AuthorObject.AddressObject.Country = "USA"
End With
ser.Serialize(writer, BookObject)
writer.Close()
End Sub
End Module
控制輸出
串行化過程產生標準的XML文件,資料成員轉換為XML元素。不過,並非所有的資料成員都變成元素,可以透過在類別程式碼中加入一些標記來控制輸出的XML檔案。這樣,資料成員可以變換為XML屬性而非元素,也可以簡單的被忽略掉。下面的例子是一段經過修改後的book類VB.NET程式碼。
Public Class Book
Public AuthorObject As Author
Public Title As String
Public ISBN As String
Public RetailPrice As Double
Public Publisher As String
End Class
這段程式碼告訴系統在產生XML檔時把類別成員ISBN當作XML屬性,同時忽略掉RetailPrice成員。這種變化可以在產生的XML檔案中可以看出:
xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance " ISBN="1884777767 ">
以下是對應的C# 程式碼:
public class Book {
public Book() { }
public string Title;
public Author AuthorObject;
[System.Xml.Serialization.XmlAttribute()]
public string ISBN;
[System.Xml.Serialization.XmlIgnoreAttribute()]
public double RetailPrice;
public string Publisher;
}
上面僅是稍微提了兩種標記符號。請查閱.NET文件以獲得完整的標記符號。
非串行化非串行化資料透過呼叫XmlSerializer類別的Deserialize方法可以方便地實現。以下的VB.NET程式片段完成上文中XML文件的非串列化:
Dim BookObject As New Book
Dim ser As New XmlSerializer(GetType(Book))
Dim fs As New System.IO.FileStream("booktest.xml", FileMode.Open)
Dim reader As New System.XML.XmlTextReader(fs)
BookObject = CType(ser.Deserialize(reader), Book)
該程式把結果資料放入記憶體備用。下面是等價的C# 程式碼:
XmlSerializer ser = new XmlSerializer(typeof(Book));
System.IO.FileStreamfs = new System.IO.FileStream("booktest.xml",
FileMode.Open);
System.Xml.XmlTextReader reader = new System.Xml.XmlTextReader(fs);
Book BookObject = (Book)(ser.Deserialize(reader));
-------------------------------------------------- -
作者簡介:Tony Patton是專業應用程式開發人員,知識面廣泛,獲得了Java、 VB、 Lotus和XML認證。