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


     

    文章正文:

    前言

      今天主要讲的是如何把通过接口获取到的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粘贴为类

     

    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.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👉

     

  • 相关阅读:
    基于springboot的校园二手网站
    内存模型和线程规范
    Java 多态
    『忘了再学』Shell基础 — 32、Shell中test测试命令详解
    想定制Android系统实现改机?看完我也会了
    天玑9000+和骁龙8gen1+哪个性能更强 两者配置对比
    RPC vs. HTTP:谁主沉浮在网络通信的江湖?
    SQLite DISTINCT 关键字
    java使用poi、itextpdf将word、ppt转为pdf文件,并对pdf文件加盖签章
    基于Java毕业设计养老机构管理信息系统源码+系统+mysql+lw文档+部署软件
  • 原文地址:https://www.cnblogs.com/Can-daydayup/p/16036890.html