最近做一个项目,要集成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 xmlpath, string xmlkey, 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是取记录总数的路径