C#实现XML系列化和反系列化的总结

常用的系列化定义(using System.Xml.Serialization;)
[XmlAttribute("name")]        // 定义<Tag name="..."></Tag>
[XmlElement("label")]        // 定义<label>...</label>
[XmlIgnoreAttribute()]        // 跳过系列化
[XmlElement("description", IsNullable = false)]        // 定义<description>...</description>,在属性值为null时不显示该元素,即可选
[XmlArray("temp_var_list", IsNullable=false)]        // 定义<temp_var_list><Tag>...</Tag>...<Tag>...</Tag></temp_var_list>,即数组对象的根结点
[XmlArrayItem("temp_var_item")]        // 定义<temp_var_item>...</temp_var_item>...<temp_var_item>...</temp_var_item>,即数据元素的根结点,常与XmlArray组合使用
[XmlRoot("dpd")]        // 定义要结点

几个注意事项
(1)需序列化的字段必须是公共的(public)
(2)需要序列化的类都必须有一个无参的构造函数
(3)枚举变量可序列化为字符串,无需用[XmlInclude]
(4)导出非基本类型对象,都必须用[XmlInclude]事先声明。该规则递归作用到子元素
 如导出ArrayList对象,若其成员是自定义的,需预包含处理:
 using System.Xml.Serialization;
 [XmlInclude(typeof(自定义类))]
(5)Attribute中的IsNullable参数若等于false,表示若元素为null则不显示该元素。
 也就是说:针对值类型(如结构体)该功能是实效的
 若数组包含了100个空间,填充了10个类对象,则序列化后只显示10个节点
 若数组包含了100个空间,填充了10个结构体对象,则序列化后会显示100个节点
(6)真正无法XML序列化的情况
 某些类就是无法XML序列化的(即使使用了[XmlInclude])
  IDictionary(如HashTable)
  System.Drawing.Color
  System.Drawing.Font
  SecurityAttribute声明
 父类对象赋予子类对象值的情况
 对象间循环引用
(7)对于无法XML序列化的对象,可考虑
 使用自定义xml序列化(实现IXmlSerializable接口)
 实现IDictionary的类,可考虑①用其它集合类替代;②用类封装之,并提供Add和this函数
 某些类型需要先经过转换,然后才能序列化为 XML。如XML序列化System.Drawing.Color,可先用ToArgb()将其转换为整数
 过于复杂的对象用xml序列化不便的话,可考虑用二进制序列化

实例
    [SerializableAttribute]        // 定义本类系列化
    [XmlRoot("dpd")]        // 定义为XML的根结点
    public class DataProcessDef

        [XmlElement("is_published")]        // 枚举类型可以系列化成字符串
        public PublishedTypes IsPublished

        [XmlElement("data_item")]        // 输出<data_item>...</data_item>
        public DataItem DataItem

        [XmlArray("property_list")]        // 组合使用,输出<property_list><property_item>...</property_item>...<property_item>...</property_item></property_list>
        [XmlArrayItem("property_item", IsNullable=false)]
        public PropertyItem[] PropertyList

        [XmlElement("custom_item", IsNullable=false)]        // 输出<custom_item>...</custom_item>...<custom_item>...</custom_item>
        public CustomItem[] CustomItems

        [XmlIgnoreAttribute()]        // 不系列化
        public String SourceName

另一种方法
namespace TestCsXml
{
    [Serializable]
    public class SubClass
    {
        public SubClass()
        {

        }

        public SubClass(String str)
        {
            _temp = str;
        }

        [XmlElement("Temp")]
        public String Temp
        {
            get
            {
                return _temp;
            }

            set
            {
                _temp = value;
            }
        }

        private String _temp;
    }

    [Serializable]
    [XmlRoot("Root")]
    [XmlInclude(typeof(SubClass))]
    public class Class1
    {
        public Class1()
        {

        }

        public Class1(String test, String name)
        {
            _test = test;
            _name = name;
        }

        [XmlElement("Test")]
        public String Test
        {
            get
            {
                return _test;
            }

            set
            {
                _test = value;
        
;    }
        }

        [XmlAttribute("Name")]
        public String Name
        {
            get
            {
                return _name;
            }

            set
            {
                _name = value;
            }
        }

        [XmlElement("Mooo")]
        public IList Lst
        {
            get
            {
                return _list;
            }

            set
            {
                _list = value;
            }
        }

        [XmlElement("Subclass")]
        public IList Subcls
        {
            get
            {
                return _listObj;
            }

            set
            {
                _listObj = value;
            }
        }

        private String _test;
        private String _name;
        private IList _list = new List<String>();
        private IList _listObj = new List<SubClass>();
    }
}

使用方法
        private void button5_Click(object sender, EventArgs e)
        {
            FileStream fs = new FileStream(@"E:\test2.xml", FileMode.Open);
            XmlSerializer sr = new XmlSerializer(typeof(DataProcessDef));
            DataProcessDef dpd = (DataProcessDef)sr.Deserialize(fs);

            TextWriter wt = new StreamWriter(@"E:\test21.xml");
            sr = new XmlSerializer(typeof(DataProcessDef));

            sr.Serialize(wt, dpd);
            wt.Close();

            MessageBox.Show("OK");
        }
 

Tags:

Leave a Reply


提醒: 评论者允许使用'@user空格'的方式将自己的评论通知另外评论者。例如, ABC是本文的评论者之一,则使用'@ABC '(不包括单引号)将会自动将您的评论发送给ABC。请务必注意user必须和评论者名相匹配(大小写一致)。