c#正反序列化XML文件示例(xml序列化)

c#正反序列化XML文件示例(xml序列化),第1张

概述复制代码代码如下:usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Reflection;usingSystem.Text;usingSystem.Text.RegularExpressions;usingSystem.Xml.Serialization;usingSystem.IO;using

复制代码 代码如下:
using System.Collections.Generic;
using System.linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml.Serialization;
using System.IO;
using System;

namespace GlobalTimes.Framework
{
    /// <summary>
    /// XML文本通用解释器
    /// </summary>
    public class XmlHelper
    {
        private const string EncodePattern = "<[^>]+?enCoding=\"(?<enc>[^<>\\s]+)\"[^>]*?>";
        private static Readonly EnCoding DefEnCoding = EnCoding.GetEnCoding("gb2312");
        private static Readonly Regex RegRoot = new Regex("<(\\w+?)[ >]",RegexOptions.Compiled);
        private static Readonly Regex RegEncode = new Regex(EncodePattern,
                                                            RegexOptions.Compiled | RegexOptions.IgnoreCase);
        private static Readonly Dictionary<string,XmlSerializer> Parsers = new Dictionary<string,XmlSerializer>();
        #region 解析器

        static EnCoding GetEnCoding(string input)
        {
            var match = RegEncode.Match(input);
            if (match.Success)
            {
                try
                {
                    return EnCoding.GetEnCoding(match.Result("${enc}"));
                }
// ReSharper disable EmptyGeneralCatchClause
                catch (Exception)
// ReSharper restore EmptyGeneralCatchClause
                {
                }
            }
            return DefEnCoding;
        }

        /// <summary>
        /// 解析XML文件
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="filename">文件名</param>
        /// <returns>类的实例</returns>
        public T Parsefile<T>(string filename) where T : class,new()
        {
            var info = new fileInfo(filename);
            if (!info.Extension.Equals(".xml",StringComparison.CurrentCultureIgnoreCase) || !info.Exists)
            {
                throw new ArgumentException("输入的文件名有误!");
            }
            string body;
            var tempfilename = PathHelper.PathOf("temp",GuID.NewGuID().ToString().Replace("-","") + ".xml");
            var fi = new fileInfo(tempfilename);
            var di = fi.Directory;
            if (di != null && !di.Exists)
            {
                di.Create();
            }
            file.copy(filename,tempfilename);
            using (Stream stream = file.Open(tempfilename,fileMode.Open,fileAccess.Read))
            {
                using (TextReader reader = new StreamReader(stream,DefEnCoding))
                {
                    body = reader.ReadToEnd();
                }
            }
            file.Delete(tempfilename);
            var enc = GetEnCoding(body);
            if (!Equals(enc,DefEnCoding))
            {
                var data = DefEnCoding.GetBytes(body);
                var dest = EnCoding.Convert(DefEnCoding,enc,data);
                body = enc.GetString(dest);
            }
            return Parse<T>(body,enc);
        }

        /// <summary>
        /// 将对象序列化为XML文件
        /// </summary>
        /// <param name="filename">文件名</param>
        /// <param name="obj">对象</param>
        /// <returns></returns>
        /// <exception cref="ArgumentException">文件名错误异常</exception>
        public bool Savefile(string filename,object obj)
        {
            return Savefile(filename,obj,DefEnCoding);
        }

        /// <summary>
        /// 将对象序列化为XML文件
        /// </summary>
        /// <param name="filename">文件名</param>
        /// <param name="obj">对象</param>
        /// <param name="enCoding"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentException">文件名错误异常</exception>
        public bool Savefile(string filename,object obj,EnCoding enCoding)
        {
            var info = new fileInfo(filename);
            if (!info.Extension.Equals(".xml",StringComparison.CurrentCultureIgnoreCase))
            {
                throw new ArgumentException("输入的文件名有误!");
            }
            if (obj == null) return false;
            var type = obj.GetType();
            var serializer = GetSerializer(type);

            using (Stream stream = file.Open(filename,fileMode.Create,fileAccess.Write))
            {
                using (TextWriter writer = new StreamWriter(stream,enCoding))
                {
                    serializer.Serialize(writer,obj);
                }
            }
            return true;
        }
        static XmlSerializer GetSerializer(Type type)
        {
            var key = type.Fullname;
            XmlSerializer serializer;
            var incl = Parsers.TryGetValue(key,out serializer);
            if (!incl || serializer == null)
            {
                var rootAttrs = new XmlAttributes { XmlRoot = new XmlRootAttribute(type.name) };
                var attrOvrs = new XmlAttributeOverrIDes();
                attrOvrs.Add(type,rootAttrs);
                try
                {
                    serializer = new XmlSerializer(type,attrOvrs);
                }
                catch (Exception e)
                {
                    throw new Exception("类型声明错误!" + e);
                }
                Parsers[key] = serializer;
            }
            return serializer;
        }
        /// <summary>
        /// 解析文本
        /// </summary>
        /// <typeparam name="T">需要解析的类</typeparam>
        /// <param name="body">待解析文本</param>
        /// <returns>类的实例</returns>
        public T Parse<T>(string body) where T : class,new()
        {
            var enCoding = GetEnCoding(body);
            return Parse<T>(body,enCoding);
        }

        /// <summary>
        /// 解析文本
        /// </summary>
        /// <typeparam name="T">需要解析的类</typeparam>
        /// <param name="body">待解析文本</param>
        /// <param name="enCoding"></param>
        /// <returns>类的实例</returns>
        public T Parse<T>(string body,EnCoding enCoding) where T : class,new()
        {
            var type = typeof (T);
            var roottagname = GetRootElement(body);

            var key = type.Fullname;
            if (!key.Contains(roottagname))
            {
                throw new ArgumentException("输入文本有误!key:" + key + "\t\troot:" + roottagname);
            }

            var serializer = GetSerializer(type);
            object obj;
            using (Stream stream = new MemoryStream(enCoding.GetBytes(body)))
            {
                obj = serializer.Deserialize(stream);
            }
            if (obj == null) return null;
            try
            {
                var rsp = (T) obj;
                return rsp;
            }
            catch (InvalIDCastException)
            {
                var rsp = new T();
                var pisr = typeof (T).GetPropertIEs();
                var piso = obj.GetType().GetPropertIEs();
                foreach (var info in pisr)
                {
                    var info1 = info;
                    foreach (var value in from propertyInfo in piso where info1.name.Equals(propertyInfo.name) select propertyInfo.GetValue(obj,null))
                    {
                        info.SetValue(rsp,value,null);
                        break;
                    }
                }
                return rsp;
            }
        }

        private static XmlSerializer BuildSerializer(Type type)
        {
            var rootAttrs = new XmlAttributes { XmlRoot = new XmlRootAttribute(type.name) };
            var attrOvrs = new XmlAttributeOverrIDes();
            attrOvrs.Add(type,rootAttrs);
            try
            {
                return new XmlSerializer(type,attrOvrs);
            }
            catch (Exception e)
            {
                throw new Exception("类型声明错误!" + e);
            }
        }

        /// <summary>
        /// 解析未知类型的XML内容
        /// </summary>
        /// <param name="body">Xml文本</param>
        /// <param name="enCoding">字符编码</param>
        /// <returns></returns>
        public object ParseUnkNown(string body,EnCoding enCoding)
        {
            var roottagname = GetRootElement(body);
            var array = AppDomain.CurrentDomain.GetAssemblIEs();
            Type type = null;
            foreach (var assembly in array)
            {
                type = assembly.GetType(roottagname,false,true);
                if (type != null) break;
            }
            if (type == null)
            {
                Logger.GetInstance().Warn("加载 {0} XML类型失败! ",roottagname);
                return null;
            }
            var serializer = GetSerializer(type);
            object obj;
            using (Stream stream = new MemoryStream(enCoding.GetBytes(body)))
            {
                obj = serializer.Deserialize(stream);
            }

            var rsp = obj;
            return rsp;
        }
        /// <summary>
        /// 用XML序列化对象
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public string Serialize(object obj)
        {
            if (obj == null) return string.Empty;
            var type = obj.GetType();
            var serializer = GetSerializer(type);
            var builder = new StringBuilder();
            using (TextWriter writer = new StringWriter(builder))
            {
                serializer.Serialize(writer,obj);
            }
            return builder.ToString();
        }
        #endregion

        /// <summary>
        /// 获取XML响应的根节点名称
        /// </summary>
        private static string GetRootElement(string body)
        {
            var match = RegRoot.Match(body);
            if (match.Success)
            {
                return match.Groups[1].ToString();
            }
            throw new Exception("InvalID XML format!");
        }

    }
}

总结

以上是内存溢出为你收集整理的c#正反序列化XML文件示例(xml序列化)全部内容,希望文章能够帮你解决c#正反序列化XML文件示例(xml序列化)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1261905.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存