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

虚幻大学 xuhss 378℃ 0评论

Python微信订餐小程序课程视频

https://edu.csdn.net/course/detail/36074

Python实战量化交易理财系统

https://edu.csdn.net/course/detail/35475思维导航:

文章正文:

?回到顶部## 前言

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

?回到顶部## 需要操作的Xml数据

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

</spanxml version="1.0" encoding="utf-8" ?>
<envelope>
 <header>
 <version port="1111" host="www.baidu.com">successfulyversion>
 <timestamp>20211216081218timestamp>
 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
{
 /// 
    /// 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 List cities { 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粘贴为类

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

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://blog.csdn.net/Can-daydayup/p/16036872.html?

?回到顶部## C#XmlHelper帮助类操作Xml文档的通用方法汇总

https://blog.csdn.net/Can-daydayup/p/16058817.html?

?回到顶部## .NET中XML序列化和反序列化常用类和用来控制XML序列化的属性总结

https://blog.csdn.net/Can-daydayup/p/16052873.html?

转载请注明:xuhss » C#复杂XML反序列化为实体对象两种方式

喜欢 (0)

您必须 登录 才能发表评论!