当前位置:   article > 正文

C# 序列化_c# 序列化 去掉xml version="1.0" encoding

c# 序列化 去掉xml version="1.0" encoding

本文示例完整代码
最近在操作Xml用常规的方法比较繁琐,用LinQ to xml比较简单,但我想说的是另外一种方法:自定义序列化
平时程序在操作将数据存入xml中,无非就是将复杂对象的属性保存到xml中,然后在有需要的时候再加载。使用xml序列化要using System.Xml.Serialization;请看如下:
1.普通对象的序列化

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;

namespace SerializationTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Test1 t = new Test1(){ Name="li",Age=890, IsChecked=true};
            FileStream fs_create=new FileStream("t.txt",FileMode.Create,FileAccess.ReadWrite);
            XmlSerializer s = new XmlSerializer(typeof(Test1));
            s.Serialize(fs_create, t);
            fs_create.Close();
            Console.WriteLine("完成");
            Console.Read();
        }
    }
    [Serializable]
    public class Test1
    {
        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        private int age;

        public int Age
        {
            get { return age; }
            set { age = value; }
        }
        private bool isChecked;

        public bool IsChecked
        {
            get { return isChecked; }
            set { isChecked = value; }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

运行,查看t.txt的内容:

<?xml version="1.0"?>
<Test1 xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Name>li</Name>
  <Age>890</Age>
  <IsChecked>true</IsChecked>
</Test1>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2.自定义序列化
我们可不可以把类序列化后得到这样的xml呢?

<?xml version="1.0"?>
<Test1 xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Instance>
  <Name value="li"></Name>
  <Age value="890"></Age>
  <IsChecked value="true"></IsChecked>
  </Instance>
</Test1>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

想达到这样的效果,就必须自定义序列化,实现IXmlSerializable接口,请看如下的实现:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using System.Reflection;
using System.Xml;

namespace SerializationTest
{
    class Class1
    {
        static void Main(string[] args)
        {
            //序列化
            Test2 t = new Test2() { Name = "li", Age = 890, IsChecked = true };
            FileStream fs_create = new FileStream("t2.txt", FileMode.Create, FileAccess.ReadWrite);
            XmlSerializer s = new XmlSerializer(typeof(Test2));
            s.Serialize(fs_create, t);
            fs_create.Close();


            //反序列化
            FileStream fs_read = new FileStream("t2.txt", FileMode.Open, FileAccess.ReadWrite);
            Test2 instance = s.Deserialize(fs_read) as Test2;
            Console.WriteLine(instance);
            //Console.WriteLine("完成");
            Console.Read();
        }
    }
    public class Test2 : IXmlSerializable
    {
        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        private int age;

        public int Age
        {
            get { return age; }
            set { age = value; }
        }
        private bool isChecked;

        public bool IsChecked
        {
            get { return isChecked; }
            set { isChecked = value; }
        }
        //实现IXmlSerializable接口
        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;
        }
        //实现IXmlSerializable接口,DeSerialize方法的具体实现
        public void ReadXml(System.Xml.XmlReader reader)
        {
            reader.Read();
            reader.ReadStartElement("Instance");
            while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
            {
                string proValue = reader.GetAttribute("value");
                string proName = reader.Name;//读取属性名称                                 
                Type proType = this.GetType().GetProperty(proName).PropertyType;
                object obj = System.ComponentModel.TypeDescriptor.GetConverter(proType).ConvertFrom(proValue);//将字符串值转换为属性值(属性值得类型不知)
                this.GetType().GetProperty(proName).SetValue(this, obj, null);               
                reader.Read();
            }
            reader.ReadEndElement();
            reader.ReadEndElement();
        }
        //实现IXmlSerializable接口,Serialize方法的具体实现
        public void WriteXml(System.Xml.XmlWriter writer)
        {
            writer.WriteStartElement("Instance");
                foreach (PropertyInfo proInfo in this.GetType().GetProperties())
                {
                    string proName = proInfo.Name;
                    string proValue = proInfo.GetValue(this, null).ToString();
                    writer.WriteStartElement(proName);//开始写属性名称的element
                    writer.WriteAttributeString("value", proValue);//写attribute
                    writer.WriteEndElement();//结束element;
                }
            writer.WriteEndElement(); //结束InstanceElement
        }
        public override string ToString()
        {
            string s = "";
            foreach (PropertyInfo info in this.GetType().GetProperties())
            {
                string proName = info.Name;
                string proValue = info.GetValue(this, null).ToString();
                s += string.Format("{0}:{1}\r\n",proName,proValue);
            }
            return s;
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104

3.自定义字典和复杂对象的序列化
上述对Test2类做了自定义序列化,有时候复杂的对象类型是这样的:
一个对象里面有一个字典,字典里面的key是string,字典的Value是Test2对象的集合。如何将这个复杂的对象序列化,然后又还原呢?
字典本身是不支持序列化的,这是我们就又要实现IXmlSerializable,对字典进行处理,代码如下:

 public class MyDictionary : Dictionary<string,List<Test2>>, IXmlSerializable
    {

        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(XmlReader reader)
        {
            XmlSerializer s = new XmlSerializer(typeof(List<Test2>));
            reader.Read();
            while (reader.NodeType != XmlNodeType.EndElement)
            {
                string key = reader.GetAttribute("key");
                reader.Read();
                reader.ReadStartElement("Value");
                this[key] = s.Deserialize(reader) as List<Test2>;
                reader.ReadEndElement();
                reader.ReadEndElement();
            }
            reader.ReadEndElement();
        }

        public void WriteXml(XmlWriter writer)
        {
            XmlSerializer s=new XmlSerializer(typeof(List<Test2>));
            foreach (string key in this.Keys)
            {
                writer.WriteStartElement("Dic");
                writer.WriteAttributeString("key",key);
                     writer.WriteStartElement("Value");
                     s.Serialize(writer, this[key]);
                     writer.WriteEndElement();
                writer.WriteEndElement();
            }
        }
        public override string ToString()
        {
            string s = "";
            foreach (string key in this.Keys)
            {
                s += "key:" + key+"\r\n";
                foreach(var i in this[key])
                {
                    s += i.ToString();
                }
                s += "\r\n";
            }
            return s;
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

然后再来一个类,聚合MyDictionary:

[Serializable]
public class Test3
{
    private MyDictionary dic;
    public MyDictionary Dic
    {
        get { return dic; }
        set { dic = value; }
    }
    private string name;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }
    public override string ToString()
    {
        string s = "";
        foreach (PropertyInfo info in this.GetType().GetProperties())
        {
            //if(this.GetType().GetProperty(info.Name).GetType().Equals(typeof(MyDictionary)))
            s += string.Format("\r\n属性名:{0},值{1}\r\n", info.Name, this.GetType().GetProperty(info.Name).GetValue(this, null).ToString());
        }
        return s;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

注意:Test3类要序列化,除了类的各个属性要能被序列化外,还要求有 [Serializable]标记,如果没有这个标记,则会出错,如果一个类直接实现了IXmlSerializable接口,则不需要[Serializable]标记可实现序列化。
在Main函数中测试Test3序列化:

 Test3 t3 = new Test3()
            {
                Name = "12345678",
                Dic = new MyDictionary()
            };
            t3.Dic.Add("abc", new List<Test2>()
                {
                    new Test2(){ Age=1, Name="fjdjf",IsChecked=false},
                    new Test2(){Age=2,Name="abcdefgh",IsChecked=true},
                    new Test2{Age=3,Name="009987876",IsChecked=true}
                });
             t3.Dic.Add("efg", new List<Test2>()
                {
                    new Test2(){ Age=4, Name="fjfffdjf",IsChecked=false},
                    new Test2(){Age=5,Name="abcdfsdfsdefgh",IsChecked=true},
                    new Test2{Age=6,Name="00998fsdfsdfds7876",IsChecked=true}
                });
             XmlSerializer t3_serialize = new XmlSerializer(typeof(Test3));
             FileStream t3_fsCreate = new FileStream("t3.xml", FileMode.Create, FileAccess.ReadWrite);
             t3_serialize.Serialize(t3_fsCreate, t3);
             t3_fsCreate.Close();

             FileStream t3_fsRead = new FileStream("t3.xml", FileMode.Open, FileAccess.ReadWrite);
             Test3 tt3= t3_serialize.Deserialize(t3_fsRead) as Test3;
             t3_fsRead.Close();
             Console.WriteLine(tt3);

             Console.WriteLine("完成");
             Console.Read();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

生成的t3.xml的文件内容如下:

<?xml version="1.0"?>
<Test3 xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Dic>
    <Dic key="abc">
      <Value>
        <ArrayOfTest2>
          <Test2>
            <Instance>
              <Name value="fjdjf" />
              <Age value="1" />
              <IsChecked value="False" />
            </Instance>
          </Test2>
          <Test2>
            <Instance>
              <Name value="abcdefgh" />
              <Age value="2" />
              <IsChecked value="True" />
            </Instance>
          </Test2>
          <Test2>
            <Instance>
              <Name value="009987876" />
              <Age value="3" />
              <IsChecked value="True" />
            </Instance>
          </Test2>
        </ArrayOfTest2>
      </Value>
    </Dic>
    <Dic key="efg">
      <Value>
        <ArrayOfTest2>
          <Test2>
            <Instance>
              <Name value="fjfffdjf" />
              <Age value="4" />
              <IsChecked value="False" />
            </Instance>
          </Test2>
          <Test2>
            <Instance>
              <Name value="abcdfsdfsdefgh" />
              <Age value="5" />
              <IsChecked value="True" />
            </Instance>
          </Test2>
          <Test2>
            <Instance>
              <Name value="00998fsdfsdfds7876" />
              <Age value="6" />
              <IsChecked value="True" />
            </Instance>
          </Test2>
        </ArrayOfTest2>
      </Value>
    </Dic>
  </Dic>
  <Name>12345678</Name>
</Test3>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

其实还可以改进,将Element减少,属性值全部存放到Attibute上,便于阅读。以后再实现。。。
本文示例完整代码

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/111838
推荐阅读
相关标签
  

闽ICP备14008679号