熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

如何使用XmlSerializer類控制串行化

2013-11-13 09:44:02  來源: .NET編程 

  人們一直高喊XML是解決系統互聯問題的關鍵NET framework 也為處理XML數據提供了許多不同的類庫 XmlDocument 類能讓你像處理文件一樣處理XML 數據 而XmlReader XmlWriter 和它們的派生類使你能夠將XML 數據做為數據流處理 XmlSerializer 則提供了另外的方法 它使你能夠將自己的對象串行和反串行化為XML 串行化數據既能夠讓你像處理文件一樣對數據進行隨機存取 同時又能夠跳過你不感興趣的元素 在本文中 我將向你展示如何使用XmlSerializer類以及如何在你的類中添加屬性來控制串行化過程

XmlSerializer
    XmlSerializer類存在於SystemXmlSerialization命名空間的SystemXmldll中 它用一種高度松散耦合的方式提供串行化服務 你的類不需要繼承特別的基類 而且它們也不需要實現任何特別的接口 相反的 你只需要在你的類或者這些類的公共域以及讀/寫屬性裡加上自定義的屬性 XmlSerializer 通過相反映射讀取這些屬性並用它們將你的類和類成員映射到XML元素和屬性

將XML 映射到對象
考慮表A中的XML語句 哪一個正確的描述了一家電影院中上映的電影呢?

表A

<?xml version= encoding=utf ?>
<theater>
 <name>The Camelot</name>
 <phone>()</phone>
 <movie minutes= stars=>
  <title>The Score</title>
  <rating>R</rating>
  <showing>::</showing>
  <showing>::</showing>
  <showing>::</showing>
 </movie>
 <movie minutes=>
  <title>Shrek</title>
  <rating>PG</rating>
  <showing>::</showing>
  <showing>::</showing>
  <showing>::</showing>
 </movie>
</theater>

  表B中定義了一個Theater(電影院)類 它包含了XmlSerializer使用的屬性映射

表B

using System;
using SystemXmlSerialization;

 namespace ArticlesTechRepublicXmlSerialization
{
    [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 += + movieToString();

                    return StringFormat(
                    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 = ;

    [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 += showingToShortTimeString() + ;
        }
        else
        {
            showings = No showings;
        }

        return StringFormat( ( min)
        Title Minutes showings );
    }
}

 

  XmlElement 屬性將Title和Showings數據域映射到movie元素內的title 和showing XML元素就象 TheaterMovie一樣 做為DateTime數組的MovieShowings 被映射到多個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 SystemXmlSerialization;
using SystemIO;
using ArticlesTechRepublicXmlSerialization;

public class XmlIn
{
    public static void Main( string[] args )
    {
        if ( argsLength != )
        {
            ConsoleWriteLine( Usage: XmlIn infilexml );
            return;
        }

        try
        {
            // Deserialize the specified file to a Theater object
            XmlSerializer xs = new XmlSerializer( typeof ( Theater ) );
            FileStream fs = new FileStream( args[] FileModeOpen );

            Theater theater = (Theater)xsDeserialize( fs );

            // Display the theater object
            ConsoleWriteLine ( theater );
        }
        catch ( Exception x )
        {
            ConsoleWriteLine( Exception: + xMessage );
        }
    }
}

Output:
>XmlIn theaterInxml
The Camelot
()

The Score ( min) shows at : PM : PM : PM
Shrek ( min) shows at : PM : PM : PM
 

  主要的程序代碼都放在Main 函數的try代碼段裡 首先創建一個XmlSerializer對象並指明一個SystemType 對象來告訴反串行化程序要創建的對象的類型 typeof操作符為Theater類返回一個SystemType 對象 然後 打開一個文件流讀取輸入的XML文件 調用XmlSerializer的Deserialize方法 並把文件流傳遞給它 Deserialize 返回對Theater對象的引用 Theater和Movie 對象中的ToString方法能夠讓你簡單的輸出它們

將對象串行化到XML裡
    從一個Theater對象生成XML數據同樣是容易的 表E中的程序XmlOut 就是將一個Theater對象串行化到XML 文件裡 這個程序通過命令行執行 你需要指明輸出的XML文件
表E


using System;
using SystemXml;
using SystemXmlSerialization;
using SystemIO;
using ArticlesTechRepublicXmlSerialization;

public class XmlOut
{
    // Returns a populated Theater object
    public static Theater GetTheater()
    {
        Movie movie = new Movie();
        movieTitle = O Brother Where Art Thou?;
        movieMinutes = ;
        movieShowings = new DateTime[];
        movieShowings[] = new DateTime( );
        movieShowings[] = new DateTime( );
        movieShowings[] = new DateTime( );

        Theater theater = new Theater();
        theaterName = Hollywood Movies ;
        theaterPhone = ();
        theaterMovies = new Movie[];
        theaterMovies[] = movie;

        return theater;
    }

    public static void Main( string[] args )
    {
        if ( argsLength != )
        {
            ConsoleWriteLine( Usage: XmlOut outfilexml );
            return;
        }

        try
        {
            Theater theater = GetTheater();

            // Serialize the Theater object to an XML file
            XmlSerializer xs = new XmlSerializer( typeof ( Theater ) );
            FileStream fs = new FileStream( args[] FileModeCreate );

            xsSerialize( fs theater );
        }
        catch ( Exception x )
        {
            ConsoleWriteLine( Exception: + xMessage );
        }
    }
}

Invocation:
>XmlOut theaterOutxml

theaterOutxml contents:

<?xml version=?>
<theater
xmlns:xsi=instance
xmlns:xsd=>

    <name>Hollywood Movies </name>
    <phone>()</phone>
    <movie minutes=>
        <title>O Brother Where Art Thou?</title>
        <showing>:::</showing>
        <showing>:::</showing>
        <showing>:::</showing>
    </movie>
</theater>

 

  主要的程序代碼都放在Main 函數的try代碼段裡 首先通過GetTheater幫助函數創建一個Theater對象 然後 打開一個文件流來生成輸出的XML 文件 調用XmlSerializer的Serialize方法 傳遞給它文件流和Theater對象 就是這樣簡單XML文件生成了!

    輸出的theater 元素包含了為模板和模板實例命名空間生成的XML命名空間屬性(xmlns) 雖然在這兩個命名空間裡這些數據並不代表任何東西 showing元素中的: 指的是美國中部時間 或者說GMT時間再減去個小時 也就是我所在的時區

移動數據是小菜一碟
    XmlSerializer 使得在對象和XML間移動數據變得非常容易 只要在類裡加上XML映射屬性 但是對於更復雜的對象模型 手工的創建XML映射會變得非常的麻煩而且容易出錯 在我的下一篇文章裡 我將告訴你如何自動化這個工作並實現對你的XML數據的更嚴格的控制


From:http://tw.wingwit.com/Article/program/net/201311/11441.html
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.