C#,NET API接口 XML数据反序列化,数据节点动态指定

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里面的泛型类型等等,不好操作赶时间没弄出来。

有好的优化建议大家可以帮忙改善下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C#中的XML序列化和反序列化是常用的技术,可以将对象转化为便于传输的XML格式,并且可以将XML格式的数据还原为对象。其中,XML序列化可以使用多种方式实现,比如二进制、字节数组、JSON字符串和XML字符串等。在C#中,可以使用XmlSerializer类的Serialize方法将对象序列化为XML字符串,使用Deserialize方法将XML字符串反序列化为对象。\[1\] 在进行XML序列化时,可以通过设置XmlTextWriter的Formatting属性为Formatting.Indented来实现换行显示,使得生成的XML字符串更加可读。另外,需要注意的是,Dictionary本身不支持序列化,所以需要重写为可序列化的SerializableDictionary类来实现对字典的序列化操作。\[2\] 对于XML反序列化为对象,可以使用deserialize方法来实现。该方法接受一个XML字符串和一个类型参数,通过使用XmlSerializer类的Deserialize方法将XML字符串反序列化指定类型的对象。在反序列化过程中,需要使用StringReader将XML字符串转化为可读的流,并使用XmlSerializer类进行反序列化操作。\[3\] #### 引用[.reference_title] - *1* *2* *3* [C# XML序列化和反序列化(XmlSerializer)](https://blog.csdn.net/sD7O95O/article/details/128783513)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值