C# XML序列化和反序列化(XmlSerializer)

概述

     XML序列化和反序列化是C#的常用技术,实现的方式有很多种,序列化即将对象转化为便于传输的数据格式, 常见的方法有:二进制,字节数组,json字符串,xml字符串等。今天主要通过XmlSerializer类的Serialize和Deserialize方法实现.

标注

     如果使用XmlSerializer类实现序列化,不需要用[Serializable]属性标记对象的类型。如果用DataContractSerializer序列化对象,则需要标注[Serializable][DataContract]

需要序列化的类型前标注 [XmlRoot("Name")],表示根节点;

[XmlType(TypeName = "Name")] 节点
[XmlElement("Name")] 元素
[XmlAttribute("Name")] 属性
[XmlArray] 声明集合

详见:微软官网:https://learn.microsoft.com/zh-cn/dotnet/standard/serialization/attributes-that-control-xml-serialization

Mark:

1. 私有属性不会被序列化;

2. 标注为[XmlIgnore]的共有属性也不会被序列化;

3. 枚举类型的属性序列化之前需要赋值

实例


using Caliburn.Micro.Hello.Helper;
using Caliburn.Micro.Hello.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace Caliburn.Micro.Hello.ViewModels
{
    public class XmlSerializerViewModel : Screen, IViewModel
    {
        private StringBuilder stringBuilder = new StringBuilder();
        public string DisplayInfo { get; set; }
        public XmlSerializerViewModel()
        {
            DisplayName = "XmlSerializer";

            xmlFile();
            SerializeToXml();
            DeserializeXml();
            DisplayInfo = stringBuilder.ToString();
        }

        public void xmlFile()
        {
            XmlFile xmlFile = new XmlFile();
            xmlFile.CreateXmlFile("ReviewParams", "maxValue", "30");
        }

        public void SerializeToXml()
        {
            //测试序列化
            var xml = "";
            StudentList de = new StudentList();

            var person1 = new Student();
            person1.Name = "郭德纲";
            person1.Age = 58;
            person1.Sex = "男";

            var person2 = new Student();
            person2.Name = "洪金宝";
            person2.Age = 72;
            person2.Sex = "男";

            de.data = new List<Student>();
            de.data.Add(person1);
            de.data.Add(person2);

            xml = XmlHelper.serialize(de);
            stringBuilder.AppendLine(xml);

            //XmlHelper.SerializeToXml(de);
            XmlHelper.SerializeToXml(new DocumentDic());
        }

        public void DeserializeXml()
        {
            var content = File.ReadAllText(Environment.CurrentDirectory + @"\myxml.xml");
            DocumentDic dee = XmlHelper.deserialize(content, typeof(DocumentDic)) as DocumentDic;
            if (dee != null)
            {
                foreach (var item in dee.dataDic.Values)
                {
                    stringBuilder.AppendLine(item.Name);
                }
            }
        }

    }
}

运行结果:

这里要注意的是  xtw.Formatting = Formatting.Indented;//可实现换行显示;Dictionary本身不支持序列化,所以需要重写为可序列化的SerializableDictionary;

SerializeToXml:

 public static void SerializeToXml(object o)
        {
            var type = o.GetType();
            if (o == null)
            {
                return;
            }

            //序列化对象
            XmlSerializer serializer = new XmlSerializer(type);
            using (XmlTextWriter xtw = new XmlTextWriter("myxml.xml", Encoding.UTF8)) //用XmlTextWriter 创建一个XML文件
            {
                xtw.Formatting = Formatting.Indented;//可实现换行显示
                serializer.Serialize(xtw, o);
            };
        }

 反序化xml为对象:


 /// <summary>
        /// 反序化xml为对象
        /// </summary>
        /// <param name="xml"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static object deserialize(string xml, Type type)
        {
            try
            {
                using (StringReader sr = new StringReader(xml))
                {
                    XmlSerializer serializer = new XmlSerializer(type);
                    return serializer.Deserialize(sr);
                }
            }
            catch (Exception e)
            {
                return null;
            }
        }

数据模型:

 //对象定义
    [XmlRoot("RecipeData")]
    //[DataContract(Name = "RecipeData", Namespace = "DataContracts")]
    [Serializable]
    public class DocumentDic
    {
        public DocumentDic()
        {
            dataDic = new SerializableDictionary<string, Student>();
            var person = new Student();
            person.Name = "韦小宝";
            person.Age = 65;
            person.Sex = "男";

            dataDic.Add("明星", person);
        }
        [XmlElement("DataTable")] //DataTable平行出现,不出现data
        //[XmlIgnore]
        //[DataMember(Name = "dataDic")]
        public SerializableDictionary<string, Student> dataDic { get; set; }
    }

    //对象定义
    [XmlRoot("StudentList")]
    public class StudentList
    {
        //[XmlArray("Students"), XmlArrayItem("Student")] 
        [XmlElement("Students")]
        public List<Student> data { get; set; }
    }

    [XmlRoot("Student")]
    public class Student
    {
        [XmlElement("Name")]
        public string Name { get; set; }

        [XmlElement("Age")]
        public int Age { get; set; }

        [XmlElement("Sex")]
        public string Sex { get; set; }

    }

此外还可以用DataContractSerializer,

DataContractSerializer 与 XMLSerializer的区别:

① 需要序列化对象的所有公共和私有字段和属性,可以使用 DataContractSerializer 而不要使用 XML 序列化。

② DataContractSerializer 的性能优于 Xmlserializer。DataContractSerializer 序列化所有标记为 [DataMember] 属性的成员,即使成员标记为私有。一个类不同时使用[Serializable]和[DataContract]标签。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值