关注XML串行化
XmlSerializer 則提供了另外的方法, 它使你能夠將自己的物件串列和反串行化爲XML. 串列化資料既能夠讓你像處理文件一樣對資料進行隨機存取, 同時又能夠跳過你不感興趣的元素. 在本文中, 我將向你展示如何使用XmlSerializer類以及如何在你的類中添加屬性來控制串列化過程.
XmlSerializer
XmlSerializer類存在於System.Xml.Serialization命名空間的System.Xml.dll中, 它用一種高度鬆散耦合的方式提供串列化服務. 你的類不需要繼承特別的基類, 而且它們也不需要實現任何特別的介面. 相反的, 你只需要在你的類或者這些類的公共域以及讀/寫屬性里加上自定義的屬性. XmlSerializer 通過相反映射讀取這些屬性並用它們將你的類和類成員映射到XML元素和屬性.
1.將XML 映射到物件
a. Theater.xml
接下来定義了一個Theater(電影院)類, 它包含了XmlSerializer使用的屬性映射.
XmlRoot 屬性將類Theater映射到XML的根元素theater. XmlElement 屬性將Name, Phone, 和 Movies資料欄映射到嵌套在theater元素中的name, phone, 和 movie XML元素上去. 因爲Movies是Movie陣列, 所以XmlSerializer將它映射到多個XML movie元素.
一個帶有屬性映射的Movie類
XmlElement 屬性將Title和Showings資料欄映射到movie元素內的title 和showing XML元素.就象 Theater.Movie一樣, 做爲DateTime陣列的Movie.Showings 被映射到多個XML showing 元素. showing 資料欄的屬性包括位置屬性參數DataType="time". 它將DateTime值映射到一個XML time值, 其間去掉了日期資訊而只保留了時間資訊. XmlAttribute 屬性將Minutes 資料欄映射到XML屬性而不是XML元素.
XML資料中的moviestars(影星)屬性和rating(上座率)元素沒有被映射到Movie類中的任何東西上去. 當反串行化XML資料的時候, XmlSerializer只是簡單的跳過它不能映射的專案. 當串列化一個物件的時候, 你可以在公共資料欄和你希望XmlSerializer跳過的屬性里加上XmlIgnore 屬性.
XmlRoot, XmlElement, 和 XmlAttribute的屬性類都應包括尾碼"Attribute." 在我的屬性申明?, 我使用了沒有尾碼的縮寫形式. Theater和Movie類中的公共屬性可以被改寫成公共屬性以求得更好的封裝性. XmlSerializer 可以用相同的方式使用它們. 我在這?將它們做爲資料欄使用是爲了使代碼更緊湊.
將XML資料反串行化成物件 將XML資料載入到一個Theater物件?現在已經變得非常容易. 表D中的程式, XmlIn, 通過反串行化movie showings XML 資料創建一個Theater物件. 這個程式通過命令行執行, 你需要指明一個輸入的XML文件.
主要的程式碼都放在Main 函數的try代碼段?. 首先創建一個XmlSerializer物件並指明一個System.Type 物件來告訴反串行化程式要創建的物件的類型. typeof操作符爲Theater類返回一個System.Type 物件. 然後, 打開一個文件流讀取輸入的XML文件. 調用XmlSerializer的Deserialize方法, 並把文件流傳遞給它. Deserialize 返回對Theater物件的引用. Theater和Movie 物件中的ToString方法能夠讓你簡單的輸出它們.
2. 將物件串列化到XML?
從一個Theater物件生成XML資料同樣是容易的. 表E中的程式,XmlOut, 就是將一個Theater物件串列化到XML 文件?. 這個程式通過命令行執行, 你需要指明輸出的XML文件.
theaterOut.xml contents:
主要的程式碼都放在Main 函數的try代碼段?. 首先通過GetTheater幫助函數創建一個Theater物件. 然後, 打開一個文件流來生成輸出的XML 文件. 調用XmlSerializer的Serialize方法, 傳遞給它文件流和Theater物件. 就是這樣簡單--XML文件生成了!
輸出的theater 元素包含了爲模板和模板實例命名空間生成的XML命名空間屬性(xmlns), 雖然在這兩個命名空間?這些資料並不代表任何東西. showing元素中的-06:00 指的是美國中部時間, 或者說GMT時間再減去6個小時.
移動資料是小菜一碟
XmlSerializer 使得在物件和XML間移動資料變得非常容易, 只要在類里加上XML映射屬性. 但是對於更複雜的物件模型, 手工的創建XML映射會變得非常的麻煩而且容易出錯. 在我的下一篇文章?, 我將告訴你如何自動化這個工作並實現對你的XML資料的更嚴格的控制.
XmlSerializer
XmlSerializer類存在於System.Xml.Serialization命名空間的System.Xml.dll中, 它用一種高度鬆散耦合的方式提供串列化服務. 你的類不需要繼承特別的基類, 而且它們也不需要實現任何特別的介面. 相反的, 你只需要在你的類或者這些類的公共域以及讀/寫屬性里加上自定義的屬性. XmlSerializer 通過相反映射讀取這些屬性並用它們將你的類和類成員映射到XML元素和屬性.
1.將XML 映射到物件
a. Theater.xml
华纳威
(888)665-2222
R
16:15:00
19:05:00
21:40:00
PG-13
16:00:00
19:00:00
21:40:00
接下来定義了一個Theater(電影院)類, 它包含了XmlSerializer使用的屬性映射.
using System;
using System.Xml.Serialization;
namespace Theater
{
[XmlRoot( "theater" )]
public class Theater
{
[XmlElement( "name" )]
public string Name = "";
[XmlElement( "phone" )]
public string Phone = "";
[XmlElement( "movie" )]
public Movie[] Movies;
public override string ToString()
{
string movies = "";
if ( Movies != null )
foreach ( Movie movie in Movies )
movies += "\n" + movie.ToString();
return String.Format( "{0}\n {1}\n{2}", Name, Phone, movies );
}
}
XmlRoot 屬性將類Theater映射到XML的根元素theater. XmlElement 屬性將Name, Phone, 和 Movies資料欄映射到嵌套在theater元素中的name, phone, 和 movie XML元素上去. 因爲Movies是Movie陣列, 所以XmlSerializer將它映射到多個XML movie元素.
一個帶有屬性映射的Movie類
public class Movie
{
[XmlElement( "title" )]
public string Title = "";
[XmlAttribute( "minutes" )]
public uint Minutes = 0;
[XmlElement( "showing", DataType="time" )]
public DateTime[] Showings;
public override string ToString()
{
string showings = "";
if ( Showings != null )
{
showings = "shows at ";
foreach ( DateTime showing in Showings )
showings += showing.ToShortTimeString() + " ";
}
else
{
showings = "- No showings";
}
return String.Format( " {0} ({1} min) {2}", Title, Minutes, showings );
}
}
XmlElement 屬性將Title和Showings資料欄映射到movie元素內的title 和showing XML元素.就象 Theater.Movie一樣, 做爲DateTime陣列的Movie.Showings 被映射到多個XML showing 元素. showing 資料欄的屬性包括位置屬性參數DataType="time". 它將DateTime值映射到一個XML time值, 其間去掉了日期資訊而只保留了時間資訊. XmlAttribute 屬性將Minutes 資料欄映射到XML屬性而不是XML元素.
XML資料中的moviestars(影星)屬性和rating(上座率)元素沒有被映射到Movie類中的任何東西上去. 當反串行化XML資料的時候, XmlSerializer只是簡單的跳過它不能映射的專案. 當串列化一個物件的時候, 你可以在公共資料欄和你希望XmlSerializer跳過的屬性里加上XmlIgnore 屬性.
XmlRoot, XmlElement, 和 XmlAttribute的屬性類都應包括尾碼"Attribute." 在我的屬性申明?, 我使用了沒有尾碼的縮寫形式. Theater和Movie類中的公共屬性可以被改寫成公共屬性以求得更好的封裝性. XmlSerializer 可以用相同的方式使用它們. 我在這?將它們做爲資料欄使用是爲了使代碼更緊湊.
將XML資料反串行化成物件 將XML資料載入到一個Theater物件?現在已經變得非常容易. 表D中的程式, XmlIn, 通過反串行化movie showings XML 資料創建一個Theater物件. 這個程式通過命令行執行, 你需要指明一個輸入的XML文件.
using System;
using System.Xml.Serialization;
using System.IO;
namespace Theater
{
public class XmlIn
{
public static void Main( string[] args )
{
if ( args.Length != 1 )
{
Console.WriteLine( "Usage: XmlIn infile.xml" );
return;
}
try
{
// Deserialize the specified file to a Theater object.
XmlSerializer xs = new XmlSerializer( typeof ( Theater ) );
FileStream fs = new FileStream( args[0], FileMode.Open );
Theater theater = (Theater)xs.Deserialize( fs );
// Display the theater object.
Console.WriteLine ( theater );
}
catch ( Exception x )
{
Console.WriteLine( "Exception: " + x.Message );
}
}
}
}
主要的程式碼都放在Main 函數的try代碼段?. 首先創建一個XmlSerializer物件並指明一個System.Type 物件來告訴反串行化程式要創建的物件的類型. typeof操作符爲Theater類返回一個System.Type 物件. 然後, 打開一個文件流讀取輸入的XML文件. 調用XmlSerializer的Deserialize方法, 並把文件流傳遞給它. Deserialize 返回對Theater物件的引用. Theater和Movie 物件中的ToString方法能夠讓你簡單的輸出它們.
2. 將物件串列化到XML?
從一個Theater物件生成XML資料同樣是容易的. 表E中的程式,XmlOut, 就是將一個Theater物件串列化到XML 文件?. 這個程式通過命令行執行, 你需要指明輸出的XML文件.
using System;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
namespace Theater
{
public class XmlOut
{
// Returns a populated Theater object.
public static Theater GetTheater()
{
Movie movie = new Movie();
movie.Title = "O Brother, Where Art Thou?";
movie.Minutes = 102;
movie.Showings = new DateTime[3];
movie.Showings[0] = new DateTime( 2001, 8, 2, 13, 15, 0 );
movie.Showings[1] = new DateTime( 2001, 8, 2, 16, 30, 0 );
movie.Showings[2] = new DateTime( 2001, 8, 2, 19, 55, 0 );
Theater theater = new Theater();
theater.Name = "Hollywood Movies 10";
theater.Phone = "(972)555-154";
theater.Movies = new Movie[1];
theater.Movies[0] = movie;
return theater;
}
public static void Main( string[] args )
{
if ( args.Length != 1 )
{
Console.WriteLine( "Usage: XmlOut outfile.xml" );
return;
}
try
{
Theater theater = GetTheater();
// Serialize the Theater object to an XML file.
XmlSerializer xs = new XmlSerializer( typeof ( Theater ) );
FileStream fs = new FileStream( args[0], FileMode.Create );
xs.Serialize( fs, theater );
}
catch ( Exception x )
{
Console.WriteLine( "Exception: " + x.Message );
}
}
}
}
theaterOut.xml contents:
Hollywood Movies 10
(972)555-154
13:15:00.0000000-06:00
16:30:00.0000000-06:00
19:55:00.0000000-06:00
主要的程式碼都放在Main 函數的try代碼段?. 首先通過GetTheater幫助函數創建一個Theater物件. 然後, 打開一個文件流來生成輸出的XML 文件. 調用XmlSerializer的Serialize方法, 傳遞給它文件流和Theater物件. 就是這樣簡單--XML文件生成了!
輸出的theater 元素包含了爲模板和模板實例命名空間生成的XML命名空間屬性(xmlns), 雖然在這兩個命名空間?這些資料並不代表任何東西. showing元素中的-06:00 指的是美國中部時間, 或者說GMT時間再減去6個小時.
移動資料是小菜一碟
XmlSerializer 使得在物件和XML間移動資料變得非常容易, 只要在類里加上XML映射屬性. 但是對於更複雜的物件模型, 手工的創建XML映射會變得非常的麻煩而且容易出錯. 在我的下一篇文章?, 我將告訴你如何自動化這個工作並實現對你的XML資料的更嚴格的控制.