(轉).NET對象的XML序列化和反序列化

        雖說是轉的,不過之前還是說點自己的感受.最近被朋友拉去參加一個面向代理的程序設計競賽,挺有意思的,類似面向服務,不過要求使用.NET平臺,雖然以前用過,不過對.NET的理解實在沒法跟JAVA比,不過越用越發現,落後的東西各有各的長處,先進的東西都是一樣一樣的,哈哈.真沒想到,連JAXB在.NET裏都有,本來還打算自己寫個類似的類庫呢,頓時對.NET好感倍增,現在JDBC也學.NET引入了類似DATASET,JAVA學引入了類似屬性的註釋類型,真的是越來越像的.反而到覺得,讓兩者區分的卻存在於語言本身,而非類庫.舉個簡單的例子,JAVA的類支持靜態代碼段,典型的設計模式上的應用就是JDBC利用這種機制實現了橋樑模式,而C#卻不能,當然,我對專門針對.NET的設計模式並不瞭解,這不代表沒法實現,就好比GOF的一些方法移到JAVA裏就可以更簡單的實現,或是JAVA語言本身就無法實現一樣,語言給我們的只是代碼級別的區別.而整體的思想大家卻都一樣,就好象這次的面向代理的運行容器也是從開源社區學JAVA的.大家的目的都是一樣的,只是途徑不通而已,各有長短而已.下面就是轉的了,只爲記錄下,以後忘了能查,對MSDN實在沒啥信心:

 

一 概述
.NET Framework爲處理XML數據提供了許多不同的類庫。XmlDocument類能讓你像處理文件一樣處理xml數據,而XmlReader、XmlWriter和它們的派生類使你能夠將xml數據作爲數據流處理。
XmlSerializer則提供了另外的方法,它使你能夠將自己的對象串行化和反串行化爲xml。串行化數據既能夠讓你像處理文件一樣對數據進行隨機處理,同時又能跳過你不感興趣的數據。
二 主要類庫介紹
   .NET 支持對象xml序列化和反序列化的類庫主要位於命名空間System.Xml.Serialization中。
   1.  XmlSerializer
   該類用一種高度鬆散耦合的方式提供串行化服務。你的類不需要繼承特別的基類,而且它們也不需要實現特別的接口。相反,你只需在你的類或者這些類的公共域以及讀/寫屬性里加上自定義的特性。XmlSerializer通過反射機制讀取這些特性並用它們將你的類和類成員映射到xml元素和屬性。
   2. XmlAttributeAttribute
   指定類的公共域或讀/寫屬性對應xml文件的Attribute。
   例:[XmlAttribute(“type”)] or [XmlAttribute(AttributeName=”type”)]
   3. XmlElementAttribute
   指定類的公共域或讀/寫屬性對應xml文件的Element。
   例:[XmlElement(“Maufacturer”)] or [XmlElement(ElementName=”Manufacturer”)]
   4. XmlRootAttribute
   Xml序列化時,由該特性指定的元素將被序列化成xml的根元素。
   例:[XmlRoot(“RootElement”)] or [XmlRoot(ElementName = “RootElements”)]
   5. XmlTextAttribute
   Xml序列化時,由該特性指定的元素值將被序列化成xml元素的值。一個類只允許擁有一個該特性類的實例,因爲xml元素只能有一個值。
   6. XmlIgnoreAttribute
   Xml序列化時不會序列化該特性指定的元素。
三 實例
   下面例子中的xml schema 描述了一個簡單的人力資源信息,其中包含了xml的大部分格式,如xml 元素相互嵌套, xml元素既有元素值,又有屬性值。
   1. 待序列化的類層次結構
    [XmlRoot("humanResource")]
    public class HumanResource
    {
        #region private data.
        private int m_record = 0;
        private Worker[] m_workers = null;
        #endregion
 
        [XmlAttribute(AttributeName="record")]
        public int Record
        {
            get { return m_record; }
            set { m_record = value; }
        }
 
        [XmlElement(ElementName="worker")]
        public Worker[] Workers
        {
            get { return m_workers; }
            set { m_workers = value; }
        }
}
 
    public class Worker
    {
        #region private data.
        private string m_number = null;
        private InformationItem[] m_infoItems = null;
        #endregion
 
        [XmlAttribute("number")]
        public string Number
        {
            get { return m_number; }
            set { m_number = value; }
        }
 
        [XmlElement("infoItem")]
        public InformationItem[] InfoItems
        {
            get { return m_infoItems; }
            set { m_infoItems = value; }
        }
}
 
    public class InformationItem
    {
        #region private data.
        private string m_name = null;
        private string m_value = null;
        #endregion
 
        [XmlAttribute(AttributeName = "name")]
        public string Name
        {
            get { return m_name; }
            set { m_name = value; }
        }
 
        [XmlText]
        public string Value
        {
            get { return m_value; }
            set { m_value = value; }
        }
}
   2. 序列化生成的xml結構
       <?xml version="1.0" ?>
- <humanResource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" record="2">
- <worker number="001">
                 <infoItem name="name">Michale</infoItem>
                 <infoItem name="sex">male</infoItem>
                 <infoItem name="age">25</infoItem>
            </worker>
- <worker number="002">
                 <infoItem name="name">Surce</infoItem>
                 <infoItem name="sex">male</infoItem>
                 <infoItem name="age">28</infoItem>
           </worker>
         </humanResource>
   3. 利用XmlSerializer類進行序列化和反序列化的實現(一般利用緩存機制實現xml文件只解析一次。)
    public sealed class ConfigurationManager
    {
        private static HumanResource m_humanResource = null;
        private ConfigurationManager(){}
 
        public static HumanResource Get(string path)
        {
            if (m_humanResource == null)
            {
                FileStream fs = null;
                try
                {
                    XmlSerializer xs = new XmlSerializer(typeof(HumanResource));
                    fs = new FileStream(path, FileMode.Open, FileAccess.Read);
                    m_humanResource = (HumanResource)xs.Deserialize(fs);
                    fs.Close();
                    return m_humanResource;
                }
                catch
                {
                    if (fs != null)
                        fs.Close();
                    throw new Exception("Xml deserialization failed!");
                }
 
            }
            else
            {
                return m_humanResource;
            }
        }
 
        public static void Set(string path, HumanResource humanResource)
        {
            if (humanResource == null)
                throw new Exception("Parameter humanResource is null!");
           
            FileStream fs = null;
            try
            {
                XmlSerializer xs = new XmlSerializer(typeof(HumanResource));
                fs = new FileStream(path, FileMode.Create, FileAccess.Write);
                xs.Serialize(fs, humanResource);
                m_humanResource = null;
                fs.Close();
            }
            catch
            {
                if (fs != null)
                    fs.Close();
                throw new Exception("Xml serialization failed!");
            }
        }
    }
四 說明
   1. 需要序列化爲xml元素的屬性必須爲讀/寫屬性;
   2. 注意爲類成員設定缺省值,儘管這並不是必須的。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章