.NET使XML序列化易如反掌

來源:互聯網
上載者:User
xml

 

人們一直高喊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>
   <name>The Camelot</name>
   <phone>(888)665-2222</phone>
   <movie minutes="120" stars="2">
   <title>The Score</title>
   <rating>R</rating>
   <showing>16:15:00</showing>
   <showing>19:05:00</showing>
   <showing>21:40:00</showing>
   </movie>
   <movie minutes="100">
   <title>Shrek</title>
   <rating>PG-13</rating>
   <showing>16:00:00</showing>
   <showing>19:00:00</showing>
   <showing>21: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的根項目theater. 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 );
  
   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 );
  
   xs.Serialize( fs, theater );
   }
   catch ( Exception x )
   {
   Console.WriteLine( "Exception: " + x.Message );
   }
   }
  }
  
  Invocation:
  >XmlOut theaterOut.xml
  
  theaterOut.xml contents:
  
  <?xml version="1.0"?>
  <theater
  xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  
   <name>Hollywood Movies 10</name>
   <phone>(972)555-154</phone>
   <movie minutes="102">
   <title>O Brother, Where Art Thou?</title>
   <showing>13:15:00.0000000-06:00</showing>
   <showing>16:30:00.0000000-06:00</showing>
   <showing>19:55:00.0000000-06:00</showing>
   </movie>
  </theater>
  
   
  
  主要的程式碼都放在Main 函數的try程式碼片段裡. 首先通過GetTheater協助函數建立一個Theater對象. 然後, 開啟一個檔案流來產生輸出的XML 檔案. 調用XmlSerializer的Serialize方法, 傳遞給它檔案流和Theater對象. 就是這樣簡單--XML檔案產生了!
  
  輸出的theater 元素包含了為模板和模板執行個體命名空間產生的XML命名空間屬性(xmlns), 雖然在這兩個命名空間裡這些資料並不代表任何東西. showing元素中的-06:00 指的是美國中部時間, 或者說GMT時間再減去個小時, 也就是我所在的時區.
  
  移動資料是小菜一碟
  XmlSerializer 使得在對象和XML間移動資料變得非常容易, 只要在類裡加上XML映射屬性. 但是對於更複雜的物件模型, 手工的建立XML映射會變得非常的麻煩而且容易出錯. 在我的下一篇文章裡, 我將告訴你如何自動化這個工作並實現對你的XML資料的更嚴格的控制.
  
  
  
  



相關文章

Alibaba Cloud 10 Year Anniversary

With You, We are Shaping a Digital World, 2009-2019

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。