【 tulaoshi.com - Web开发 】
                             
                            人们一直高喊XML是解决系统互联问题的关键, 而.NET framework 也为处理XML数据提供了许多不同的类库. XmlDocument 类能让你像处理文件一样处理XML 数据, 而XmlReader, XmlWriter, 和它们的派生类使你能够将XML 数据做为数据流处理. XmlSerializer 则提供了另外的方法, 它使你能够将自己的对象串行和反串行化为XML. 串行化数据既能够让你像处理文件一样对数据进行随机存取, 同时又能够跳过你不感兴趣的元素. 在本文中, 我将向你展示如何使用XmlSerializer类以及如何在你的类中添加属性来控制串行化过程. 
   
  XmlSerializer 
  XmlSerializer类存在于System.Xml.Serialization命名空间的System.Xml.dll中, 它用一种高度松散耦合的方式提供串行化服务. 你的类不需要继承特别的基类, 而且它们也不需要实现任何特别的接口. 相反的, 你只需要在你的类或者这些类的公共域以及读/写属性里加上自定义的属性. XmlSerializer 通过相反映射读取这些属性并用它们将你的类和类成员映射到XML元素和属性. 
   
  将XML 映射到对象 
  考虑表A中的XML语句, 哪一个正确的描述了一家电影院中上映的电影呢? 
   
  表A 
   
  ?xml version="1.0" encoding="utf-8" ? 
  theater 
   nameThe Camelot/name 
   phone(888)665-2222/phone 
   movie minutes="120" stars="2" 
   titleThe Score/title 
   ratingR/rating 
   showing16:15:00/showing 
   showing19:05:00/showing 
   showing21:40:00/showing 
   /movie 
   movie minutes="100" 
   titleShrek/title 
   ratingPG-13/rating 
   showing16:00:00/showing 
   showing19:00:00/showing 
   showing21:40:00/showing 
   /movie 
  /theater 
   
   
   
  表B中定义了一个Theater(电影院)类, 它包含了XmlSerializer使用的属性映射. 
   
  表B 
   
  using System; 
  using System.Xml.Serialization; 
   
   namespace Articles.TechRepublic.XmlSerialization 
  { 
   [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的根元素theat
(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/webkaifa/)sp;  
   Theater theater = (Theater)xs.Deserialize( fs );    
   // Display the theater object. 
   Console.WriteLine ( theater ); 
   } 
   catch ( Exception x ) 
   { 
   Console.WriteLine( "Exception: " + x.Message ); 
   } 
   } 
  }    
  Output: 
  XmlIn theaterIn.xml 
  The Camelot 
  (888)665-2222    
  The Score (120 min) shows at 4:15 PM 7:05 PM 9:40 PM 
  Shrek (100 min) shows at 4:00 PM 7:00 PM 9:40 PM           
  主要的程序代码都放在Main 函数的try代码段里. 首先创建一个XmlSerializer对象并指明一个System.Type 对象来告诉反串行化程序要创建的对象的类型. typeof操作符为Theater类返回一个System.Type 对象. 然后, 打开一个文件流读取输入的XML文件. 调用XmlSerializer的Deserialize方法, 并把文件流传递给它. Deserialize 返回对Theater对象的引用. Theater和Movie 对象中的ToString方法能够让你简单的输出它们.    
  将对象串行化到XML里 
  从一个Theater对象生成XML数据同样是容易的. 表E中的程序,XmlOut, 就是将一个Theater对象串行化到XML 文件里. 这个程序通过命令行执行, 你需要指明输出的XML文件.    
  表E    
  using System; 
  using System.Xml; 
  using System.Xml.Serialization; 
  using System.IO; 
  using Articles.TechRepublic.XmlSerialization;    
  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 );    
er. XmlElement 属性将Name, Phone, 和 Movies数据域映射到嵌套在theater元素中的name, phone, 和 movie XML元素上去. 因为Movies是Movie数组, 所以XmlSerializer将它映射到多个XML movie元素.    
  表C展示了一个带有属性映射的Movie类    
  表C    
   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文件.    
  表D    
  using System; 
  using System.Xml.Serialization; 
  using System.IO; 
  using Articles.TechRepublic.XmlSerialization;    
  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 ); 
&nb