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

博客 动态
0 213
羽尘
羽尘 2022-04-01 23:57:27
悬赏:0 积分 收藏

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??

 

posted @ 2022-04-01 23:14 追逐时光者 阅读(15) 评论(1) 编辑 收藏 举报
回帖
    羽尘

    羽尘 (王者 段位)

    2335 积分 (2)粉丝 (11)源码

     

    温馨提示

    亦奇源码

    最新会员