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

代码如下:

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

}
}

(0)

相关推荐

  • C#实现复杂XML的序列化与反序列化

    本文以一个实例的形式讲述了C#实现复杂XML的序列化与反序列化的方法.分享给大家供大家参考.具体方法如下: 已知.xml(再此命名default.xml)文件,请将其反序列化到一个实例对象. Default.XML文件如下: <?xml version="1.0" encoding="utf-8" ?> <config> <rules> <rule name="namea"> <params&

  • C#序列化与反序列化(Serialize,Deserialize)实例详解

    本文实例讲述了C#序列化与反序列化(Serialize,Deserialize)实现方法.分享给大家供大家参考.具体分析如下: 如果要保存运行程序过程的数据要么保存到数据库中,要么新建一个普通的文件,然后把数据保存进去.但是这两者有个缺点就是,不能把原有数据的结构也保存进去.比如一个类中的字段值保存进去后再读取出来必须再解析下才行.序列化技术让你省去了解析的过程.保存后再读取时直接得到一个class 序列化的方式有三种:BinaryFormatter,SoapFormatter,XmlSeria

  • c#对象反序列化与对象序列化示例详解

    1.对象序列化的介绍 (1).NET支持对象序列化的几种方式二进制序列化:对象序列化之后是二进制形式的,通过BinaryFormatter类来实现的,这个类位于System.Runtime.Serialization.Formatters.Binary命名空间下.SOAP序列化:对象序列化之后的结果符合SOAP协议,也就是可以通过SOAP 协议传输,通过System.Runtime.Serialization.Formatters.Soap命名空间下的SoapFormatter类来实现的.XML

  • C#实现XML与实体类之间相互转换的方法(序列化与反序列化)

    本文实例讲述了C#实现XML与实体类之间相互转换的方法.分享给大家供大家参考,具体如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Data; using System.Xml; using System.Xml.Serialization; /// <summary> /// Xml序列化与反序列化 //

  • C#实现Xml序列化与反序列化的方法

    本文实例讲述了C#实现Xml序列化与反序列化的方法.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: /// <summary> /// Xml序列化与反序列化 /// </summary> public class XmlUtil { public static string GetRoot(string xml) {     XmlDocument doc = new XmlDocument();     doc.LoadXml(xml.Replace("

  • 浅谈C# 序列化与反序列化几种格式的转换

    这里介绍了几种方式之间的序列化与反序列化之间的转换 首先介绍的如何序列化,将object对象序列化常见的两种方式即string和xml对象; 第一种将object转换为string对象,这种比较简单没有什么可谈的: public string ScriptSerialize<T>(T t) { JavaScriptSerializer serializer = new JavaScriptSerializer(); return serializer.Serialize(t); } 第二种将o

  • C#实现xml文件反序列化读入数据到object的方法

    本文实例讲述了C#实现xml文件反序列化读入数据到object的方法.分享给大家供大家参考.具体实现方法如下: public static object DeSerializeFromXmlString(System.Type typeToDeserialize, string xmlString) { byte[] bytes = System.Text.Encoding.UTF8.GetBytes(xmlString); MemoryStream memoryStream = new Mem

  • C#反序列化到类的实现方法

    本文实例讲述了C#反序列化到类的实现方法.分享给大家供大家参考.具体实现方法如下: using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization.Formatters.Binary; using System.Text; using System.Threading.Tasks; using System.IO; using 二进制序列化; namespa

  • C#实现的json序列化和反序列化代码实例

    using System; using System.Collections.Generic; using System.Web.Script.Serialization; using System.Configuration; using System.Runtime.Serialization.Json; using System.Runtime.Serialization; using System.IO; using System.Text; namespace WebApplicati

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

    复制代码 代码如下: 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{    /// <summar

  • jQ处理xml文件和xml字符串的方法(详解)

    1.xml文件 <?xml version="1.0" encoding="utf-8" ?> <root> <book id="1"> <name>锋利的jQuery1</name> <author>XXX1</author> <price>250</price> </book> <book id="2&quo

  • JavaScript操作XML文件之XML读取方法

    本文实例讲述了JavaScript操作XML文件之XML读取方法.分享给大家供大家参考.具体分析如下: 假设我们现在要读取下面的 info.xml 文件 <?xml version="1.0" encoding="gb2312"?> <root> <data id="1"> <name>ceun</name> <age>21</age> </data>

  • Python中使用dom模块生成XML文件示例

    在Python中解析XML文件也有Dom和Sax两种方式,这里先介绍如何是使用Dom解析XML,这一篇文章是Dom生成XML文件,下一篇文章再继续介绍Dom解析XML文件. 在生成XML文件中,我们主要使用下面的方法来完成. 主要方法 1.生成XML节点(node) 复制代码 代码如下: createElement("node_name") 2.给节点添加属性值(Attribute) 复制代码 代码如下: node.setAttribute("att_name",

  • Python创建xml文件示例

    本文实例讲述了Python创建xml文件的方法.分享给大家供大家参考,具体如下: 这是一个使用ElementTree有关类库,生成xml文件的例子 # *-* coding=utf-8 from xml.etree.ElementTree import ElementTree from xml.etree.ElementTree import Element from xml.etree.ElementTree import SubElement from xml.etree.ElementTr

  • c#操作xml文件示例

    1. 新增XML文件 复制代码 代码如下: XMLToolV2 _xmlHelper = new XMLToolV2(@"C:\20140311blogs.xml");//xml保存路径或者读取路径 _xmlHelper.Create("Person", "utf-8");//跟节点名称:person;encode:utf-8 XmlElement _person = _xmlHelper.CreateElec("Name",

  • IE下JS读取xml文件示例代码

    使用JS读取xml文件,这里暂只考虑IE浏览器 step1 创建DOM对象 复制代码 代码如下: function createDom() { var xmlDoc = null; try { //IE if (typeof arguments.callee.activeXString != 'string') { var versions = [ "MSXML2.DOMDocument.6.0", "MSXML2.DOMDocument.3.0", "M

  • JS读取XML文件示例代码

    复制代码 代码如下: //读取XML文件 function loadXML(xmlFile) { var xmlDoc; if (window.ActiveXObject) { xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); xmlDoc.async = false; xmlDoc.load(xmlFile); } else if (document.implementation && document.implement

  • C++读入XML文件示例

    最近要做一个VRP的算法,测试集都是放在Xml文件中,而我的算法使用C++来写,所以需要用C++来读取Xml文件. 在百度上搜"C++读取Xml文件",可以出来很多博客,大多数是关于tinyXml的,所以这篇博文也是讲述如何用tinyXML来读取XML文件. tinyXml是一个免费开源的C++库,可以到官网上下载:https://sourceforge.net/projects/tinyxml/. 下载下来解压之后,可以看到下面这些文件: 我是在windows下用VS来写C++的,按

  • Python使用sax模块解析XML文件示例

    本文实例讲述了Python使用sax模块解析XML文件.分享给大家供大家参考,具体如下: XML样例: <?xml version="1.0"?> <collection shelf="New Arrivals"> <movie title="Enemy Behind"> <type>War, Thriller</type> <format>DVD</format>

随机推荐