欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-12-20 11:50:28
复制代码 代码如下:using system.collections.generic;using system.linq;using system.refl...

复制代码 代码如下:

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!");
        }

    }
}

上一篇:

下一篇: