NET对象的XML序列化和反序列化

NET对象的XML序列化和反序列化[url=javascript:d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(saveit=window.open('http://wz.csdn.net/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'saveit','scrollbars=no,width=590,height=300,left=75,top=20,status=no,resizable=yes'));saveit.focus();]收藏[/url] 序列化的概念
序列化是指一个对象的实例可以被保存,保存成一个二进制串,当然,一旦被保存成二进制串,那么也可以保存成文本串了。
比如,一个计数器,数值为2,我们可以用字符串“2”表示。
如果有个对象,叫做connter,当前值为2,那么可以序列化成“2”,反向的,也可以从“2”得到值为2的计数器实例。
这样,关机时序列化它,开机时反序列化它,每次开机都是延续的。不会都是从头开始。
序列化概念的提出和实现,可以使我们的应用程序的设置信息保存和读取更加方便。
序列化有很多好处,比如,在一台机器上产生一个实例,初始化完毕,然后可以序列化,通过网络传送到另一台机器,然后反序列化,得到对象实例,之后再执行某些业务逻辑,得到结果,再序列化,返回第一台机器,第一台机器得到对象实例,得到结果。
这个例子是目前比较先进的“智能代理”的原理。
当前比较热火的web services使用soap协议,soap协议也是以对象的可序列化为基础的。
一 概述
.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" ?>
[url=file:///E:/humans.xml##]-[/url] <humanResource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" record="2">
[url=file:///E:/humans.xml##]-[/url] <worker number="001">
                <infoItem name="name">Michale</infoItem>
                <infoItem name="sex">male</infoItem>
                <infoItem name="age">25</infoItem>
           </worker>
[url=file:///E:/humans.xml##]-[/url] <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. 注意为类成员设定缺省值,尽管这并不是必须的。

posted on 2009-06-16 00:53  timo.li  阅读(507)  评论(0编辑  收藏  举报

导航