C#复杂XML反序列化为实体对象两种方式
前言
今天主要讲的是如何把通过接口获取到的Xml数据转换成(反序列化)我们想要的实体对象,当然Xml反序列化和Json反序列化的方式基本上都是大同小异。都是我们事先定义好对应的对应的Xml实体模型,不过Xml是通过XmlSerializer类的相关特性来对实体对象和 XML文档之间进行序列化和反序列化操作的。序列化和反序列化其实都还好,我们可以调用封装好的XmlHelper帮助类即可实现,最关键的是我们该如何去定义这些实体模型(Model)。当你遇到对方接口一下子返回一大串的Xml数据并且里面存在很多不同的Xml节点,你该怎么办一个一个去解析这些节点到模型上去吗?本文我主要讲两种方式,第一种方法是通过手写的方式去定义Xml的实体对象模型类,第二种方法是通过Visual Studio自带的生成Xml实体对象模型类。
需要操作的Xml数据
注意:以下是我稍微简化的Xml数据,实际数据可能比这里要复杂个大几倍。
successfuly 20211216081218
一、通过是手写的方式去定义Xml的实体对象模型类
当然假如你有耐心、时间充足并且眼睛好的话可以使用这种手写的方式去定义,很多情况写到最好都会把自己给写糊涂了(可能是我年纪大了的原因)。
namespace Practices.Models { /// /// Envelope /// [XmlType(TypeName = "envelope")] public class CityDataModel { /// /// header /// [XmlElement("header")] public Header header { get; set; }/// /// response /// [XmlElement("response")] public Response response { get; set; }}/// /// Header /// [XmlType(TypeName = "header")] public class Header { /// /// version /// [XmlElement("version")] public Version version { get; set; }/// /// timestamp /// [XmlElement("timestamp")] public string timestamp { get; set; } }/// /// Version /// public class Version { /// /// port /// [XmlAttribute("port")] public string port { get; set; }/// /// host /// [XmlAttribute("host")] public string host { get; set; }/// /// value:XmlTextAttribute指示该属性作为XML文本处理 /// [XmlTextAttribute()] public string value { get; set; }}/// /// Response /// [XmlType(TypeName = "response")] public class Response { /// /// type /// [XmlAttribute] public string type { get; set; }/// /// product /// [XmlAttribute] public string product { get; set; }/// /// cities /// [XmlArray("cities")] public Listcities { get; set; }}/// /// class: City /// [XmlType(TypeName = "city")] public class City { /// /// code /// [XmlElement("code")] public Code code { get; set; }/// /// city_tax /// [XmlElement("city_tax")] public City_tax city_tax { get; set; }/// /// names /// [XmlArray("names")] public List names { get; set; } }/// /// class: Code /// [XmlType(TypeName = "code")] public class Code { /// /// /// [XmlAttribute("value")] public string value { get; set; }}/// /// class: City_tax /// [XmlType(TypeName = "city_tax")] public class City_tax { /// /// /// [XmlAttribute("value")] public string value { get; set; }}/// /// class: Name /// [XmlType(TypeName = "name")] public class Name { /// /// /// [XmlAttribute("language")] public string language { get; set; }/// /// /// [XmlAttribute("value")] public string value { get; set; }} }
二、通过Visual Studio自带的生成Xml实体对象模型类
Vs被称为宇宙最强IDE也不是没有理由的,它集成了很多自动创建功能,如自动生成Json类、Xml类等,虽然说使用Vs自动生成的Xml模型可读性有点差并且有些冗余,但是快捷省事,只需要略微改动一下即可使用。1、首先Ctrl+C复制你需要生成的Xml文档内容
2、找到编辑=》选择性粘贴=》将Xml粘贴为类
![C#复杂XML反序列化为实体对象两种方式](https://img.it610.com/image/info8/88cbc91e3d3e4c3d88896e1b28da0e20.jpg)
文章图片
3、以下是使用VS自动生成的Xml类
namespace Practices.Models {// 注意: 生成的代码可能至少需要 .NET Framework 4.5 或 .NET Core/Standard 2.0。 ///[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; /// public envelopeHeader header { get { return this.headerField; } set { this.headerField = value; } }/// public envelopeResponse response { get { return this.responseField; } set { this.responseField = value; } } }/// [System.SerializableAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] public partial class envelopeHeader {private envelopeHeaderVersion versionField; private ulong timestampField; /// public envelopeHeaderVersion version { get { return this.versionField; } set { this.versionField = value; } }/// public ulong timestamp { get { return this.timestampField; } set { this.timestampField = value; } } }/// [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; /// [System.Xml.Serialization.XmlAttributeAttribute()] public ushort port { get { return this.portField; } set { this.portField = value; } }/// [System.Xml.Serialization.XmlAttributeAttribute()] public string host { get { return this.hostField; } set { this.hostField = value; } }/// [System.Xml.Serialization.XmlTextAttribute()] public string Value { get { return this.valueField; } set { this.valueField = value; } } }/// [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; /// [System.Xml.Serialization.XmlArrayItemAttribute("city", IsNullable = false)] public envelopeResponseCity[] cities { get { return this.citiesField; } set { this.citiesField = value; } }/// [System.Xml.Serialization.XmlAttributeAttribute()] public string type { get { return this.typeField; } set { this.typeField = value; } }/// [System.Xml.Serialization.XmlAttributeAttribute()] public string product { get { return this.productField; } set { this.productField = value; } } }/// [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; /// public envelopeResponseCityCode code { get { return this.codeField; } set { this.codeField = value; } }/// public envelopeResponseCityCity_tax city_tax { get { return this.city_taxField; } set { this.city_taxField = value; } }/// [System.Xml.Serialization.XmlArrayItemAttribute("name", IsNullable = false)] public envelopeResponseCityName[] names { get { return this.namesField; } set { this.namesField = value; } } }/// [System.SerializableAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] public partial class envelopeResponseCityCode {private string valueField; /// [System.Xml.Serialization.XmlAttributeAttribute()] public string value { get { return this.valueField; } set { this.valueField = value; } } }/// [System.SerializableAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] public partial class envelopeResponseCityCity_tax {private bool valueField; /// [System.Xml.Serialization.XmlAttributeAttribute()] public bool value { get { return this.valueField; } set { this.valueField = value; } } }/// [System.SerializableAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] public partial class envelopeResponseCityName {private string languageField; private string valueField; /// [System.Xml.Serialization.XmlAttributeAttribute()] public string language { get { return this.languageField; } set { this.languageField = value; } }/// [System.Xml.Serialization.XmlAttributeAttribute()] public string value { get { return this.valueField; } set { this.valueField = value; } } }}
验证两个Xml类是否能够反序列化成功
/// /// 读取Xml文件内容反序列化为指定的对象 /// /// Xml文件的位置(绝对路径) ///public static T DeserializeFromXml (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.cnblogs.com/Can-daydayup/p/16036872.html
C#XmlHelper帮助类操作Xml文档的通用方法汇总 https://www.cnblogs.com/Can-daydayup/p/16058817.html
.NET中XML序列化和反序列化常用类和用来控制XML序列化的属性总结 https://www.cnblogs.com/Can-daydayup/p/16052873.html
【C#复杂XML反序列化为实体对象两种方式】
推荐阅读
- 初学者能学会的数据结构与算法|数算部分-----第一节----算法的时空复杂度
- dll反编译(修改引用文件、修改代码)再生成dll
- Python文件的应用之序列化与反序列化详解
- 腾讯一面(CORS为什么能保障安全(为什么只对复杂请求做预检?))
- CommonCollection1反序列化学系
- 数据结构|反转链表-四种方法
- 利用js文件反弹shell
- Python实现xml格式转txt格式的示例代码
- 【数据结构·水滴计划】|【数据结构】一篇文章带你彻底吃透·算法复杂度
- 字符串反转和句子反转(字符串逆序和句子逆序)