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