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!");
}
}
}
相关文章
- 我们在使用C#做项目的时候,基本上都需要制作登录界面,那么今天我们就来一步步看看,如果简单的实现登录界面呢,本文给出2个例子,由简入难,希望大家能够喜欢。...2020-06-25
- 这篇文章主要介绍了C# 字段和属性的的相关资料,文中示例代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下...2020-11-03
- 这篇文章主要介绍了C#中截取字符串的的基本方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-03
- 本文给大家分享C#连接SQL数据库和查询数据功能的操作技巧,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友参考下吧...2021-05-17
- 这篇文章主要介绍了C#实现简单的Http请求的方法,以实例形式较为详细的分析了C#实现Http请求的具体方法,需要的朋友可以参考下...2020-06-25
- 本文主要介绍了C#中new的几种用法,具有很好的参考价值,下面跟着小编一起来看下吧...2020-06-25
使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序)
这篇文章主要介绍了使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25- 这篇文章主要介绍了C#开发Windows窗体应用程序的简单操作步骤,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-12
- 这篇文章主要介绍了C#从数据库读取图片并保存的方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2021-01-16
- 最近做一个小项目不可避免的需要前端脚本与后台进行交互。由于是在asp.net中实现,故问题演化成asp.net中jiavascript与后台c#如何进行交互。...2020-06-25
- 这篇文章主要用实例讲解C#递归算法的概念以及用法,文中代码非常详细,帮助大家更好的参考和学习,感兴趣的朋友可以了解下...2020-06-25
- 本文通过例子,讲述了C++调用C#的DLL程序的方法,作出了以下总结,下面就让我们一起来学习吧。...2020-06-25
- 轻松学习C#的基础入门,了解C#最基本的知识点,C#是一种简洁的,类型安全的一种完全面向对象的开发语言,是Microsoft专门基于.NET Framework平台开发的而量身定做的高级程序设计语言,需要的朋友可以参考下...2020-06-25
- 本文主要介绍了C#变量命名规则小结,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-09
- 这篇文章主要介绍了c#中(&&,||)与(&,|)的区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
- 本文主要介绍了C# 中取绝对值的函数。具有很好的参考价值。下面跟着小编一起来看下吧...2020-06-25
- 这篇文章主要介绍了C#绘制曲线图的方法,以完整实例形式较为详细的分析了C#进行曲线绘制的具体步骤与相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了c#自带缓存使用方法,包括获取数据缓存、设置数据缓存、移除指定数据缓存等方法,需要的朋友可以参考下...2020-06-25
- 下面小编就为大家带来一篇C#学习笔记- 随机函数Random()的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
- 这篇文章主要介绍了C#中list用法,结合实例形式分析了C#中list排序、运算、转换等常见操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25