xml与object 之间的ORM
xml映射为object对象,同时object对象,以xml来表示:
public class Tools { private static XmlNodeList SelectNodes(string xpath, string path) { XmlDocument doc = new XmlDocument(); doc.Load(path); return doc.SelectNodes(xpath); } private static XmlNode SelectSingleNode(string xpath, string path) { XmlDocument doc = new XmlDocument(); doc.Load(path); return doc.SelectSingleNode(xpath); } public static T SelectSingle<T>(string selectNode, string path) where T : IxmlToObject<T>, new() { T item = new T(); var node = SelectSingleNode(selectNode, path); if (node != null) { T obj = item.XmlToObject(node); } return item; } public static void SaveXml(IxmlFormat obj, string path) { XmlDocument doc = new XmlDocument(); var xml = obj.ToXml(); doc.LoadXml(xml); doc.Save(path); } public static List<T> SelectList<T>(string selectNode,string path) where T:new() { List<T> items = new List<T>(); var nodes = SelectNodes(selectNode,path); if (nodes != null) { var type = typeof(T); var properties = type.GetProperties().ToList(); foreach (XmlNode node in nodes) { T config = new T(); foreach (XmlAttribute a in node.Attributes) { string name = a.Name; string value = a.Value; var p = properties.FirstOrDefault(t => t.Name.ToLower() == name.ToLower()); if (p != null) { p.SetValue(config, value, null); } } items.Add(config); } } return items; } public static string ReplaceSpecialChars(string content) { if (string.IsNullOrEmpty(content)) return ""; string[] specialChars = { "&", "<", ">", "\"", "'" }; string[] entities = { "&", "<", ">", """, "'" }; int i = 0; foreach (var item in specialChars) { content = content.Replace(item, entities[i]); i++; } return content; } }
这是公共的接口:
public interface IxmlFormat { string ToXml(); } public interface IxmlToObject<T> { T XmlToObject(XmlNode node); }
下面是自定义Object对象对接口的实现:
public class TestCase : IxmlFormat, IxmlToObject<TestCase> { public string Title { set; get; } public string Author { set; get; } public string BibType { set; get; } /// <summary> /// 测试用例路径 /// </summary> public string FilePath { set; get; } public List<SearchResult> StandardResults { set; get; } public List<SearchResult> SearchResults { set; get; } public string ToXml() { var title = Tools.ReplaceSpecialChars(this.Title); var author = Tools.ReplaceSpecialChars(this.Author); var bibType = Tools.ReplaceSpecialChars(this.BibType); StringBuilder sb = new StringBuilder(); sb.Append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>"); if (SearchResults != null && SearchResults.Count > 0) { sb.AppendFormat("<case title=\"{0}\" author=\"{1}\" bibType=\"{2}\" >", title, author, bibType); foreach (SearchResult item in SearchResults) { sb.AppendFormat("<item title=\"{0}\">", Tools.ReplaceSpecialChars(item.Title)); foreach (var fitem in item.Fields) { sb.AppendFormat("<field content=\"{0}\"/>", Tools.ReplaceSpecialChars(fitem)); } sb.AppendFormat("</item>"); } sb.Append("</case>"); } return sb.ToString(); } public TestCase XmlToObject(XmlNode node) { string title = node.Attributes["title"].Value; string author = node.Attributes["author"].Value; string bibType = node.Attributes["bibType"].Value; this.Title = title; this.Author = author; this.BibType = bibType; this.StandardResults = new List<SearchResult>(); XmlNodeList itemNodes = node.SelectNodes("//item"); foreach (XmlNode n in itemNodes) { var sr = new SearchResult() { Title = n.Attributes["title"].Value, Fields = new List<string>() }; var fileds = n.ChildNodes; foreach (XmlNode fn in fileds) { sr.Fields.Add(fn.Attributes["content"].Value); } this.StandardResults.Add(sr); } return this; } } public class SearchResult { public string Title { set; get; } public List<string> Fields { set; get; } }
这是一个测试用例,程序从xml文件中读取测试用例,运行测试程序,完成后把结果保存到另外一个xml文件中,这个xml文件结构和测试用例的xml结构一样。我们看看如何读取测试用例:
/// <summary> /// 读取测试用例 /// </summary> /// <returns></returns> private static List<TestCase> GetTestCase(string caseDir) { List<TestCase> tests = new List<TestCase>(); var files = Directory.GetFiles(caseDir); foreach (var f in files) { var filePath = f; var testCase = Tools.SelectSingle<TestCase>("//case", filePath); testCase.FilePath = filePath; tests.Add(testCase); } return tests; }
保存测试结果:
TestCase t = new TestCase() { FilePath = viewModel.FilePath, Author = viewModel.SearchAuthor, Title = viewModel.SearchTitle, BibType = viewModel.SearchType, SearchResults = viewModel.TestResultData, StandardResults = viewModel.StandardResults }; string path = viewModel.TestResultFilePath + "\\" + viewModel.ResolveName; if (!Directory.Exists(path)) Directory.CreateDirectory(path); path += "\\" + Path.GetFileNameWithoutExtension(t.FilePath) + "_data.xml"; Tools.SaveXml(t, path);
注意:对象与xml之间的转换,再转为xml时,注意特殊符号的转义,否则会报错。