XML返回数据格式
<?xml version=\"1.0\" encoding=\"gb2312\"?>
<res>
<resultCode>1</resultCode>
<resultDesc>成功</resultDesc>
<deptInfo>
<deptId>科室代码</deptId>
<deptName>科室名称</deptName>
<deptType>科室类别</deptType>
<floorInfo>楼层信息</floorInfo>
<description>科室简介</description>
<tel>咨询电话</tel>
<hospitalId>医院机构代码</hospitalId>
<hospitalName>医院机构名称</hospitalName>
</deptInfo>
<deptInfo>
<deptId>科室代码1</deptId>
<deptName>科室名称1</deptName>
<deptType>科室类别1</deptType>
<floorInfo>楼层信息1</floorInfo>
<description>科室简介1</description>
<tel>咨询电话1</tel>
<hospitalId>医院机构代码1</hospitalId>
<hospitalName>医院机构名称1</hospitalName>
</deptInfo>
</res>
<res> <resultCode> <resultDesc> 节点格式不变
<deptInfo> 节点为动态数据 接口返回接口不一个 节点名称也不一样
创建数据实体类
/// <summary>
/// His响应参数基础类
/// </summary>
public class BaseResponse
{
/// <summary>
/// 1成功
/// </summary>
public int resultCode { get; set; }
/// <summary>
/// 描述
/// </summary>
public string resultDesc { get; set; }
}
/// <summary>
/// 返回带有参数的结果
/// </summary>
/// <typeparam name="T"></typeparam>
public class BaseResponse<T> : BaseResponse where T : class
{
public T Data { get; set; }
}
/// <summary>
/// 部门信息
/// </summary>
public class deptInfo
{
public string deptId { get; set; }
public string deptName { get; set; }
public string deptType { get; set; }
public string floorInfo { get; set; }
public string description { get; set; }
public string tel { get; set; }
public string hospitalId { get; set; }
public string hospitalName { get; set; }
}
反序列化操作类
public static class XmlHelper
{
/// <summary>
/// Xml转成对象实例
/// </summary>
/// <param name="xml"></param>
/// <param name="RootNode">根据指定节点转对象,多个平级节点请用|分割</param>
/// <returns></returns>
public static T XmlNodeToEntity<T>(string xml, string RootNode = "", int GetPoI = 0, string XmlValName = "", string xmlDataNode = "") where T : new()
{
T item = new T();
try
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
//XmlNode node = doc.ChildNodes[0];
//循环列表
XmlNodeList xl_node = null;
int NodeCount = 1;
string[] NodeSplit;
NodeSplit = RootNode.Split('|');
if (string.IsNullOrEmpty(RootNode))
{
xl_node = doc.ChildNodes; ///包含所有的数据列表的节点
}
else
{
NodeCount = NodeSplit.Length;
xl_node = doc.GetElementsByTagName(NodeSplit[0]);//包含指定的数据列表的节点
}
for (int i = 0; i < NodeCount; i++)
{
if (i > 0) { xl_node = doc.GetElementsByTagName(NodeSplit[i]); }
int CalcPoI = 0;
foreach (XmlNode node in xl_node)
{
CalcPoI++;
if (GetPoI == CalcPoI || GetPoI == 0)
{
foreach (XmlNode child in node.ChildNodes)
{
if (child.NodeType == XmlNodeType.Element)
{
XmlElement element = (XmlElement)child;
System.Reflection.PropertyInfo[] propertyInfo =
typeof(T).GetProperties(System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Instance);
string attrName = element.Name.ToLower().Replace("-", "_");
string attrValue = element.InnerText;
string attrxml = element.InnerXml;
foreach (System.Reflection.PropertyInfo pinfo in propertyInfo)
{
if (pinfo != null)
{
string name = pinfo.Name.ToLower();
Type dbType = pinfo.PropertyType;
if (name == attrName)
{
if (String.IsNullOrEmpty(attrValue))
continue;
switch (dbType.ToString())
{
case "System.Int32":
pinfo.SetValue(item, Convert.ToInt32(attrValue), null);
break;
case "System.Boolean":
pinfo.SetValue(item, Convert.ToBoolean(attrValue), null);
break;
case "System.DateTime":
pinfo.SetValue(item, Convert.ToDateTime(attrValue), null);
break;
case "System.Decimal":
pinfo.SetValue(item, Convert.ToDecimal(attrValue), null);
break;
case "System.Double":
pinfo.SetValue(item, Convert.ToDouble(attrValue), null);
break;
default:
if (XmlValName.IndexOf("|" + name + "|") >= 0)
{
pinfo.SetValue(item, attrxml, null);
}
else
{
pinfo.SetValue(item, attrValue, null);
}
break;
}
break;
}
}
}
}
}
}
}
}
}
catch (Exception ex)
{
item = default(T);
}
return item;
}
/// <summary>
/// XML 反序列化 自定义返回数据XML节点
/// </summary>
/// <typeparam name="T">返回类型,单个为类 T,多个为List<T></typeparam>
/// <typeparam name="T2">数据节点类型,为类名 T</typeparam>
/// <param name="xml">要序列化的xml内容</param>
/// <param name="RootNode">数据根节点名称</param>
/// <param name="DataNode">返回数据节点名称,不填为T2的类名</param>
/// <param name="dataTag">返回数据类属性名</param>
/// <returns></returns>
public static T DESerializer<T, T2>(string xml, string RootNode = "Response", string DataNode = "", string dataTag = "Data") where T : new() where T2 : class, new()
{
T t = new T();
try
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
t = XmlNodeToEntity<T>(xml, RootNode);
if (string.IsNullOrEmpty(DataNode))
{
DataNode = typeof(T2).Name;
}
if (t != null && !string.IsNullOrEmpty(DataNode))
{
System.Reflection.PropertyInfo[] propertyInfo =
typeof(T).GetProperties(System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Instance);
foreach (System.Reflection.PropertyInfo pinfo in propertyInfo)
{
if (pinfo != null)
{
string name = pinfo.Name;
Type dbType = pinfo.PropertyType;
XmlNodeList nodeList = doc.SelectSingleNode(RootNode).ChildNodes;
if (name == dataTag)//泛型动态数据属性字段名称
{
if (nodeList == null || nodeList.Count == 0)
continue;
if (dbType.Name.Contains("List"))
{
IList<T2> list = new List<T2>();
foreach (XmlNode dataNode in nodeList)
{
if (dataNode.Name == DataNode)
{
T2 t1 = new T2();
var dataXml = dataNode.OuterXml;
if (dataXml != null && !string.IsNullOrEmpty(dataXml))
{
using (StringReader sr = new StringReader(dataXml))
{
XmlSerializer serializer = new XmlSerializer(typeof(T2));
t1 = serializer.Deserialize(sr) as T2;
list.Add(t1);
}
}
}
}
pinfo.SetValue(t, list, null);
}
else if (dbType.IsClass)
{
foreach (XmlNode dataNode in nodeList)
{
if (dataNode.Name == DataNode)
{
T2 t1 = new T2();
var dataXml = dataNode.OuterXml;
if (dataXml != null && !string.IsNullOrEmpty(dataXml))
{
using (StringReader sr = new StringReader(dataXml))
{
XmlSerializer serializer = new XmlSerializer(typeof(T2));
t1 = serializer.Deserialize(sr) as T2;
}
pinfo.SetValue(t, t1, null);
}
}
}
}
}
}
}
}
}
catch (Exception ex)
{
t = default(T);
}
return t;
}
}
方法调用:
string xml = "<?xml version=\"1.0\" encoding=\"gb2312\"?><res><resultCode>1</resultCode><resultDesc>成功</resultDesc><deptInfo><deptId>科室代码</deptId><deptName>科室名称</deptName><deptType>科室类别</deptType><floorInfo>楼层信息</floorInfo><description>科室简介</description><tel>咨询电话</tel><hospitalId>医院机构代码</hospitalId><hospitalName>医院机构名称</hospitalName></deptInfo><deptInfo><deptId>科室代码1</deptId><deptName>科室名称1</deptName><deptType>科室类别1</deptType><floorInfo>楼层信息1</floorInfo><description>科室简介1</description><tel>咨询电话1</tel><hospitalId>医院机构代码1</hospitalId><hospitalName>医院机构名称1</hospitalName></deptInfo></res>";
//返回单个对象
var obj= XmlHelper.DESerializer<BaseResponse<deptInfo>, deptInfo>(xml,RootNode:"res");
//返回List
var objList= XmlHelper.DESerializer<BaseResponse<List<deptInfo>>, deptInfo>(xml,RootNode:"res");
//无返回数据
var result = XmlHelper.DESerializer<BaseResponse>(xml, "res");
PS:这种调用写法看起来有点鸡肋,只是暂时实现了功能
理想的写法是不需要T2这个参数就能转换到对应的类型就完美了,试过了反射创建实例并赋值,判断T里面的泛型类型等等,不好操作赶时间没弄出来。
有好的优化建议大家可以帮忙改善下