C#复杂XML反序列化为实体对象两种方式小结

作者:追逐时光者 时间:2022-08-05 16:50:45 

前言

今天主要讲的是如何把通过接口获取到的Xml数据转换成(反序列化)我们想要的实体对象,当然Xml反序列化和Json反序列化的方式基本上都是大同小异。都是我们事先定义好对应的对应的Xml实体模型,不过Xml是通过XmlSerializer类的相关特性来对实体对象和 XML文档之间进行序列化和反序列化操作的。序列化和反序列化其实都还好,我们可以调用封装好的XmlHelper帮助类即可实现,最关键的是我们该如何去定义这些实体模型(Model)。当你遇到对方接口一下子返回一大串的Xml数据并且里面存在很多不同的Xml节点,你该怎么办一个一个去解析这些节点到模型上去吗?本文我主要讲两种方式,第一种方法是通过手写的方式去定义Xml的实体对象模型类,第二种方法是通过Visual Studio自带的生成Xml实体对象模型类。

需要操作的Xml数据

注意:以下是我稍微简化的Xml数据,实际数据可能比这里要复杂个大几倍。

<?xml version="1.0" encoding="utf-8" ?>
<envelope>
   <header>
       <version port="1111" host="www.baidu.com">successfuly</version>
       <timestamp>20211216081218</timestamp>
   </header>
   <response type="cities" product="hotel">
       <cities>
           <city>
               <code value="zg" />
               <city_tax value="true" />
               <names>
                   <name language="fr" value="ABANO TERME - PADOUE" />
                   <name language="en" value="ABANO TERME - PADUE" />
                   <name language="nl" value="ABANO TERME - PADUE" />
               </names>
           </city>
           <city>
               <code value="hk" />
               <city_tax value="false" />
               <names>
                   <name language="fr" value="ABBADIA SAN SALVATORE - SIENNE" />
                   <name language="en" value="ABBADIA SAN SALVATORE - SIENA" />
                   <name language="nl" value="ABBADIA SAN SALVATORE - SIENA" />
               </names>
           </city>
       </cities>
   </response>
</envelope>

一、通过是手写的方式去定义Xml的实体对象模型类

当然假如你有耐心、时间充足并且眼睛好的话可以使用这种手写的方式去定义,很多情况写到最好都会把自己给写糊涂了(可能是我年纪大了的原因)。

namespace Practices.Models
{
   /// <summary>
   /// Envelope
   /// </summary>
   [XmlType(TypeName = "envelope")]
   public class CityDataModel
   {
       /// <summary>
       /// header
       /// </summary>
       [XmlElement("header")]
       public Header header { get; set; }

/// <summary>
       /// response
       /// </summary>
       [XmlElement("response")]
       public Response response { get; set; }

}

/// <summary>
   /// Header
   /// </summary>
   [XmlType(TypeName = "header")]
   public class Header
   {
       /// <summary>
       /// version
       /// </summary>
       [XmlElement("version")]
       public Version version { get; set; }

/// <summary>
       /// timestamp
       /// </summary>
       [XmlElement("timestamp")]
       public string timestamp { get; set; }
   }

/// <summary>
   /// Version
   /// </summary>
   public class Version
   {
       /// <summary>
       /// port
       /// </summary>
       [XmlAttribute("port")]
       public string port { get; set; }

/// <summary>
       /// host
       /// </summary>
       [XmlAttribute("host")]
       public string host { get; set; }

/// <summary>
       /// value:XmlTextAttribute指示该属性作为XML文本处理
       /// </summary>
       [XmlTextAttribute()]
       public string value { get; set; }

}

/// <summary>
   /// Response
   /// </summary>
   [XmlType(TypeName = "response")]
   public class Response
   {
       /// <summary>
       /// type
       /// </summary>
       [XmlAttribute]
       public string type { get; set; }

/// <summary>
       /// product
       /// </summary>
       [XmlAttribute]
       public string product { get; set; }

/// <summary>
       /// cities
       /// </summary>
       [XmlArray("cities")]
       public List<City> cities { get; set; }

}

/// <summary>
   /// class: City
   /// </summary>
   [XmlType(TypeName = "city")]
   public class City
   {
       /// <summary>
       /// code
       /// </summary>
       [XmlElement("code")]
       public Code code { get; set; }

/// <summary>
       /// city_tax
       /// </summary>
       [XmlElement("city_tax")]
       public City_tax city_tax { get; set; }

/// <summary>
       /// names
       /// </summary>
       [XmlArray("names")]
       public List<Name> names { get; set; }
   }

/// <summary>
   /// class: Code
   /// </summary>
   [XmlType(TypeName = "code")]
   public class Code
   {
       /// <summary>
       ///
       /// </summary>
       [XmlAttribute("value")]
       public string value { get; set; }

}

/// <summary>
   /// class: City_tax
   /// </summary>
   [XmlType(TypeName = "city_tax")]
   public class City_tax
   {
       /// <summary>
       ///
       /// </summary>
       [XmlAttribute("value")]
       public string value { get; set; }

}

/// <summary>
   /// class: Name
   /// </summary>
   [XmlType(TypeName = "name")]
   public class Name
   {
       /// <summary>
       ///
       /// </summary>
       [XmlAttribute("language")]
       public string language { get; set; }

/// <summary>
       ///
       /// </summary>
       [XmlAttribute("value")]
       public string value { get; set; }

}
}

二、通过Visual Studio自带的生成Xml实体对象模型类

Vs被称为宇宙最强IDE也不是没有理由的,它集成了很多自动创建功能,如自动生成Json类、Xml类等,虽然说使用Vs自动生成的Xml模型可读性有点差并且有些冗余,但是快捷省事,只需要略微改动一下即可使用。

1、首先Ctrl+C复制你需要生成的Xml文档内容

2、找到编辑=》选择性粘贴=》将Xml粘贴为类

C#复杂XML反序列化为实体对象两种方式小结

3、以下是使用VS自动生成的Xml类

namespace Practices.Models
{

// 注意: 生成的代码可能至少需要 .NET Framework 4.5 或 .NET Core/Standard 2.0。
   /// <remarks/>
   [System.SerializableAttribute()]
   [System.ComponentModel.DesignerCategoryAttribute("code")]
   //TODO:注意这里因为我把类名改成了我自定义的,所以在TypeName这里需要声明Xml文档的节点名
   [System.Xml.Serialization.XmlTypeAttribute(typeName: "envelope")]
   [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
   public partial class NewCityDataModel
   {

private envelopeHeader headerField;

private envelopeResponse responseField;

/// <remarks/>
       public envelopeHeader header
       {
           get
           {
               return this.headerField;
           }
           set
           {
               this.headerField = value;
           }
       }

/// <remarks/>
       public envelopeResponse response
       {
           get
           {
               return this.responseField;
           }
           set
           {
               this.responseField = value;
           }
       }
   }

/// <remarks/>
   [System.SerializableAttribute()]
   [System.ComponentModel.DesignerCategoryAttribute("code")]
   [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
   public partial class envelopeHeader
   {

private envelopeHeaderVersion versionField;

private ulong timestampField;

/// <remarks/>
       public envelopeHeaderVersion version
       {
           get
           {
               return this.versionField;
           }
           set
           {
               this.versionField = value;
           }
       }

/// <remarks/>
       public ulong timestamp
       {
           get
           {
               return this.timestampField;
           }
           set
           {
               this.timestampField = value;
           }
       }
   }

/// <remarks/>
   [System.SerializableAttribute()]
   [System.ComponentModel.DesignerCategoryAttribute("code")]
   [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
   public partial class envelopeHeaderVersion
   {

private ushort portField;

private string hostField;

private string valueField;

/// <remarks/>
       [System.Xml.Serialization.XmlAttributeAttribute()]
       public ushort port
       {
           get
           {
               return this.portField;
           }
           set
           {
               this.portField = value;
           }
       }

/// <remarks/>
       [System.Xml.Serialization.XmlAttributeAttribute()]
       public string host
       {
           get
           {
               return this.hostField;
           }
           set
           {
               this.hostField = value;
           }
       }

/// <remarks/>
       [System.Xml.Serialization.XmlTextAttribute()]
       public string Value
       {
           get
           {
               return this.valueField;
           }
           set
           {
               this.valueField = value;
           }
       }
   }

/// <remarks/>
   [System.SerializableAttribute()]
   [System.ComponentModel.DesignerCategoryAttribute("code")]
   [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
   public partial class envelopeResponse
   {

private envelopeResponseCity[] citiesField;

private string typeField;

private string productField;

/// <remarks/>
       [System.Xml.Serialization.XmlArrayItemAttribute("city", IsNullable = false)]
       public envelopeResponseCity[] cities
       {
           get
           {
               return this.citiesField;
           }
           set
           {
               this.citiesField = value;
           }
       }

/// <remarks/>
       [System.Xml.Serialization.XmlAttributeAttribute()]
       public string type
       {
           get
           {
               return this.typeField;
           }
           set
           {
               this.typeField = value;
           }
       }

/// <remarks/>
       [System.Xml.Serialization.XmlAttributeAttribute()]
       public string product
       {
           get
           {
               return this.productField;
           }
           set
           {
               this.productField = value;
           }
       }
   }

/// <remarks/>
   [System.SerializableAttribute()]
   [System.ComponentModel.DesignerCategoryAttribute("code")]
   [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
   public partial class envelopeResponseCity
   {

private envelopeResponseCityCode codeField;

private envelopeResponseCityCity_tax city_taxField;

private envelopeResponseCityName[] namesField;

/// <remarks/>
       public envelopeResponseCityCode code
       {
           get
           {
               return this.codeField;
           }
           set
           {
               this.codeField = value;
           }
       }

/// <remarks/>
       public envelopeResponseCityCity_tax city_tax
       {
           get
           {
               return this.city_taxField;
           }
           set
           {
               this.city_taxField = value;
           }
       }

/// <remarks/>
       [System.Xml.Serialization.XmlArrayItemAttribute("name", IsNullable = false)]
       public envelopeResponseCityName[] names
       {
           get
           {
               return this.namesField;
           }
           set
           {
               this.namesField = value;
           }
       }
   }

/// <remarks/>
   [System.SerializableAttribute()]
   [System.ComponentModel.DesignerCategoryAttribute("code")]
   [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
   public partial class envelopeResponseCityCode
   {

private string valueField;

/// <remarks/>
       [System.Xml.Serialization.XmlAttributeAttribute()]
       public string value
       {
           get
           {
               return this.valueField;
           }
           set
           {
               this.valueField = value;
           }
       }
   }

/// <remarks/>
   [System.SerializableAttribute()]
   [System.ComponentModel.DesignerCategoryAttribute("code")]
   [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
   public partial class envelopeResponseCityCity_tax
   {

private bool valueField;

/// <remarks/>
       [System.Xml.Serialization.XmlAttributeAttribute()]
       public bool value
       {
           get
           {
               return this.valueField;
           }
           set
           {
               this.valueField = value;
           }
       }
   }

/// <remarks/>
   [System.SerializableAttribute()]
   [System.ComponentModel.DesignerCategoryAttribute("code")]
   [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
   public partial class envelopeResponseCityName
   {

private string languageField;

private string valueField;

/// <remarks/>
       [System.Xml.Serialization.XmlAttributeAttribute()]
       public string language
       {
           get
           {
               return this.languageField;
           }
           set
           {
               this.languageField = value;
           }
       }

/// <remarks/>
       [System.Xml.Serialization.XmlAttributeAttribute()]
       public string value
       {
           get
           {
               return this.valueField;
           }
           set
           {
               this.valueField = value;
           }
       }
   }

}

验证两个Xml类是否能够反序列化成功

/// <summary>    
       /// 读取Xml文件内容反序列化为指定的对象  
       /// </summary>    
       /// <param name="filePath">Xml文件的位置(绝对路径)</param>  
       /// <returns></returns>    
       public static T DeserializeFromXml<T>(string filePath)
       {
           try
           {
               if (!File.Exists(filePath))
                   throw new ArgumentNullException(filePath + " not Exists");
               using (StreamReader reader = new StreamReader(filePath))
               {
                   XmlSerializer xs = new XmlSerializer(typeof(T));
                   T ret = (T)xs.Deserialize(reader);
                   return ret;
               }
           }
           catch (Exception ex)
           {
               return default(T);
           }
       }

C# XML基础入门(XML文件内容增删改查清)

https://www.jb51.net/article/243168.htm

C#XmlHelper帮助类操作Xml文档的通用方法汇总

https://www.jb51.net/article/242389.htm

.NET中XML序列化和反序列化常用类和用来控制XML序列化的属性总结

https://www.jb51.net/article/243165.htm

来源:https://www.cnblogs.com/Can-daydayup/p/16036890.html

标签:C#,XML,反序列化,实体对象
0
投稿

猜你喜欢

  • Spring Boot实现分布式系统中的服务发现和注册(最新推荐)

    2022-07-10 03:50:23
  • maven profile自动切换环境参数的2种方法详解

    2022-10-28 09:18:39
  • spring mvc实现文件上传与下载功能

    2022-05-13 09:50:14
  • mybatis中数据加密与解密的实现

    2022-04-21 22:49:16
  • mall整合SpringTask实现定时任务的方法示例

    2023-09-15 18:08:08
  • MyBatis特殊字符转义拦截器问题针对(_、\\、%)

    2023-09-12 00:46:39
  • springboot 防止重复请求防止重复点击的操作

    2021-09-19 16:03:00
  • Spring Security 中如何让上级拥有下级的所有权限(案例分析)

    2022-01-28 16:55:26
  • C#生成EMF矢量图形文件示例详解

    2022-10-30 02:12:56
  • Java调用Shell命令和脚本的实现

    2023-11-29 00:59:09
  • 用java在web环境下上传和下载文件的技巧

    2021-06-09 18:17:17
  • 一篇文章轻松搞懂Java中的自旋锁

    2023-06-29 00:00:36
  • Java获取指定字符串出现次数的方法

    2022-05-11 16:06:23
  • c# 钩子学习笔记

    2023-03-31 20:54:22
  • 剑指Offer之Java算法习题精讲数组与字符串

    2021-05-24 19:21:45
  • JDK动态代理,代理接口没有实现类,实现动态代理方式

    2021-12-21 11:55:22
  • Eclipse+Java+Swing实现学生成绩管理系统的实例代码

    2022-12-14 15:35:04
  • C#程序提示“正由另一进程使用,因此该进程无法访问该文件”的解决办法

    2022-06-27 04:34:11
  • Java多线程Callable接口实现代码示例

    2021-08-06 14:29:01
  • SpringCloud之Config配置中心与Redis分布式锁详解

    2023-12-21 02:14:41
  • asp之家 软件编程 m.aspxhome.com