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)