最近做一个项目,要集成N多系统,单点登录和取待办任务,各个系统返回数据格式各不相同,有的是xml,有的是json,即便同样是返回xml或者json,其键值也可能不一样,因此,写了一个通用方法来解析xml和json,下面是代码
/// <summary> /// 将xml解析成指定格式数据 /// </summary> /// <param name="xmlstr">xml字符串</param> /// <param name="xmlpath">xml路径</param> /// <param name="xmlkey">xml键值</param> /// <param name="tpath">xml总数路径</param> /// <returns></returns> public static TaskModel GetListByXml(string xmlstr,string xmlpath,string xmlkey,string tpath) { TaskModel tm = null; if (string.IsNullOrEmpty(xmlstr)) return null; XmlNodeList xnl = ConfigHelper.GetXmlNodeListByXmlDoc(xmlstr,xmlpath,null); if (xnl == null) return null; if (string.IsNullOrEmpty(xmlkey)) { return null; } string[] colarr = xmlkey.Split('|'); if (colarr.Length != 2) return null; List<TaskVM> tlist = new List<TaskVM>(); foreach (XmlNode xn in xnl) { TaskVM vm = new TaskVM(); XmlNodeList sxnl = xn.ChildNodes; foreach (XmlNode sxn in sxnl) { string name = sxn.Name; //string lname = sxn.LocalName; if (colarr[0] == name) { vm.TaskName = sxn.InnerText; continue; } if (colarr[1] == name) { vm.FqTime = sxn.InnerText; continue; } } tlist.Add(vm); } int tasknum = 0; XmlNode txn = ConfigHelper.GetSingleXmlNodeByXmlDoc(xmlstr,tpath); if (txn != null && ValidHelper.IsIntData(txn.InnerText)) { tasknum = Convert.ToInt32(txn.InnerText); } if (tm == null) tm = new TaskModel(); tm.TaskList = tlist; tm.Total = tasknum==0?tlist.Count:tasknum; return tm; } /// <summary> /// 将Json解析成指定格式数据 /// </summary> /// <param name="xmlstr">xml字符串</param> /// <param name="xmlpath">xml路径</param> /// <param name="xmlkey">xml键值</param> /// <param name="tpath">xml总数路径</param> /// <returns></returns> public static TaskModel GetListByJson(string xmlstr,string tpath) { TaskModel tm = null; if (string.IsNullOrEmpty(xmlstr)) return null; string[] keycol = xmlpath.Split(new string[]{"/"},StringSplitOptions.RemoveEmptyEntries); JsonSerializer serializer = new JsonSerializer(); StringReader sr = new StringReader(xmlstr); JObject json = (JObject)serializer.Deserialize(new JsonTextReader(sr)); int tasknum = 0; tm = new TaskModel(); List<TaskVM> tlist = new List<TaskVM>(); if(!string.IsNullOrEmpty(xmlkey) && !string.IsNullOrEmpty(xmlpath)) { string[] colarr = xmlkey.Split('|'); if (colarr.Length != 2) return null; int index = 0; foreach (var item in json) { string key = item.Key; if (key.Equals(keycol[index])) { index++; if (index >= keycol.Length) { //数据肯定是Jarray JArray ja = (JArray)item.Value; foreach (JToken jobj in ja) { TaskVM vm = new TaskVM(); foreach (JProperty jp in jobj) { if (jp.Name != colarr[0] && jp.Name != colarr[1]) continue; if (jp.Name == colarr[0]) { vm.TaskName = jp.Value.ToString(); continue; } if (jp.Name == colarr[1]) { vm.FqTime = jp.Value.ToString(); continue; } } tlist.Add(vm); } break; } } } if (!string.IsNullOrEmpty(tpath)) { string[] arr = tpath.Split(new string[] { "/" },StringSplitOptions.RemoveEmptyEntries); int sy = 0; foreach (var item in json) { string key = item.Key; if (key == arr[sy]) { sy++; if (sy >= arr.Length) { string numstr = item.Value.ToString(); if (ValidHelper.IsIntData(numstr)) { tasknum = Convert.ToInt32(numstr); } break; } } } } } if (tm == null) tm = new TaskModel(); tm.TaskList = tlist; tm.Total = tasknum==0?tlist.Count:tasknum; return tm; }
其中xmlpath值就是相对于根的路径,xml的xmlpath就不说了,jsonpath,这里暂且这样叫吧,也按照数据相对于根的地址写,不同级的键,用/隔开就行。
xmlkey就是要取的键值,比如json的数据列表键值为:items,其中对应的标题键是Title,时间是date,xmlkey就写成:Title|date
tpath是取记录总数的路径