XML序列化

XmlSerializer xmlSer = new XmlSerializer(typeof(Class1));
MemoryStream writer = new MemoryStream();

Class1 c2 = new Class1();
c2.b = "123";
c2.c = 333;
c2.cc = new Class2[2];
c2.cc[0] = new Class2();
c2.cc[0].bb = 223;
c2.cc[1] = new Class2();
c2.cc[1].bb = 555;

xmlSer.Serialize(writer, c2);

StreamReader sr = new StreamReader(writer);
var str = Encoding.UTF8.GetString(writer.ToArray());

Console.WriteLine(str);
Console.ReadLine();
writer.Flush();
writer.Close();

 

 

反序列化

XmlSerializer serializer = new XmlSerializer(typeof(Class1));
TextReader reader = new StringReader(str);
Class1 c1 = (Class1)serializer.Deserialize(reader);

 

 

 

附上序列化助手类

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

namespace Hont
{
    public static class XmlSerializableHelper
    {
        #region Memory
        public static T DeSerializerFromMemory<T>(Stream stream)
        {
            XmlSerializer xmlSer = new XmlSerializer(typeof(T));
            return (T)xmlSer.Deserialize(stream);
        }

        public static Stream SerializerToMemory(object obj)
        {
            XmlSerializer xmlSer = new XmlSerializer(obj.GetType());
            MemoryStream writer = new MemoryStream();

            xmlSer.Serialize(writer, obj);

            return writer;
        }
        #endregion

        #region Disk
        public static T DeSerializerFromDisk<T>(string path)
        {
            return DeSerializerFromString<T>(File.ReadAllText(path));
        }

        public static void SerializerToDisk(string path, object obj, Encoding encoding)
        {
            var serResult = SerializerToString(obj);
            if (File.Exists(path)) File.Delete(path);
            File.AppendAllText(path, serResult, encoding);
        }
        #endregion

        #region String
        public static T DeSerializerFromString<T>(string xml)
        {
            XmlSerializer xmlSer = new XmlSerializer(typeof(T));
            TextReader reader = new StringReader(xml);
            return (T)xmlSer.Deserialize(reader);
        }

        public static string SerializerToString(object obj)
        {
            XmlSerializer xmlSer = new XmlSerializer(obj.GetType());
            MemoryStream writer = new MemoryStream();

            xmlSer.Serialize(writer, obj);

            StreamReader sr = new StreamReader(writer);
            var str = Encoding.UTF8.GetString(writer.ToArray());

            writer.Flush();
            writer.Close();
            sr.Close();

            return str;
        }
        #endregion
    }
}
XmlSerializableHelper

 

 需要注意几点:

1.需要无参数的构造函数

2.对于不可序列化的复杂类型,用特殊特性去标记,并实现序列化接口,具体msdn查询IXmlSerializable

3.不支持只读字段的序列化。

4.微软自己的序列化,对可空类型的支持比较糟糕。尽量避免序列化可空类型

5.[System.Xml.Serialization.XmlIgnore]可以使成员忽略序列化

6.不支持字典类型,但网上有一个扩展"可序列化字典":

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace SerializableDictionary
{
    [XmlRoot("dictionary"), Serializable]
    public class SerializableDictionary<TKey, TValue>
        : Dictionary<TKey, TValue>, IXmlSerializable
    {
        public SerializableDictionary()
        {
        }

        public SerializableDictionary(IDictionary<TKey, TValue> dictionary)
            : base(dictionary)
        {
        }

        public SerializableDictionary(IEqualityComparer<TKey> comparer)
            : base(comparer)
        {
        }


        public SerializableDictionary(int capacity)
            : base(capacity)
        {
        }

        public SerializableDictionary(int capacity, IEqualityComparer<TKey> comparer)
            : base(capacity, comparer)
        {
        }

        protected SerializableDictionary(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }

        #region IXmlSerializable Members

        public XmlSchema GetSchema()
        {
            return null;
        }

        /// <summary>
        /// 从对象的 XML 表示形式生成该对象
        /// </summary>
        /// <param name="reader"></param>
        public void ReadXml(XmlReader reader)
        {
            var keySerializer = new XmlSerializer(typeof(TKey));
            var valueSerializer = new XmlSerializer(typeof(TValue));
            bool wasEmpty = reader.IsEmptyElement;
            reader.Read();

            if (wasEmpty)
                return;
            while (reader.NodeType != XmlNodeType.EndElement)
            {
                reader.ReadStartElement("item");
                reader.ReadStartElement("key");
                var key = (TKey)keySerializer.Deserialize(reader);
                reader.ReadEndElement();
                reader.ReadStartElement("value");
                var value = (TValue)valueSerializer.Deserialize(reader);
                reader.ReadEndElement();
                Add(key, value);
                reader.ReadEndElement();
                reader.MoveToContent();
            }
            reader.ReadEndElement();
        }

        /// <summary>
        /// 将对象转换为其 XML 表示形式
        /// </summary>
        /// <param name="writer"></param>
        public void WriteXml(XmlWriter writer)
        {
            var keySerializer = new XmlSerializer(typeof(TKey));
            var valueSerializer = new XmlSerializer(typeof(TValue));
            foreach (TKey key in Keys)
            {
                writer.WriteStartElement("item");
                writer.WriteStartElement("key");
                keySerializer.Serialize(writer, key);
                writer.WriteEndElement();
                writer.WriteStartElement("value");
                TValue value = this[key];
                valueSerializer.Serialize(writer, value);
                writer.WriteEndElement();
                writer.WriteEndElement();
            }
        }

        #endregion
    }
}
View Code

7.支持抽象类的序列化

8.ArrayList和Hashtable以及System.Collections的常规集合类型都支持的不太好。ArrayList只支持值类型,不支持结构。

9.报错InvalidOperationException: The type of the argument object 'xxx' is not primitive.,解决方法xml不知道实际的弱类型,你需要传过去。如下:

var xmlSer = new XmlSerializer(list.GetType(), new System.Type[] { typeof(A1), typeof(A2) });

10.可以序列化属性,但必须是Get,Set的

posted @ 2014-09-06 21:45  HONT  阅读(682)  评论(0编辑  收藏  举报