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
C#复杂XML反序列化为实体对象两种方式的更多相关文章
- Java中将xml文件转化为json的两种方式
原文地址https://blog.csdn.net/a532672728/article/details/76312475 最近有个需求,要将xml转json之后存储在redis中,找来找去发现整体来 ...
- ABAP和XML数据格式互相转换的两种方式
ABAP和XML数据格式互相转换是广大开发人员经常遇到的需求.本文介绍两种方式. 1. ABAP提供了一个工具类cl_proxy_xml_transform,通过它的两个方法abap_to_xml_x ...
- redis 存储java对象 两种方式
根据redis的存储原理,Redis的key和value都支持二进制安全的字符串 1.利用序列化和反序列化的方式存储java对象我们可以通过对象的序列化与反序列化完成存储于取出,这样就可以使用redi ...
- 查询list转化为tree的两种方式及排序
方式一,数据库查询tree; MyBatis collection 集合 MyBatis 是数据持久层框架,支持定制化 SQL.存储过程以及高级映射.尤其强大在于它的映射语句,比如高级映射中的 col ...
- 通过获取客户端Json数据字符串,反序列化为实体对象的一段代码
#region 保存候选人数据 /// <summary> /// 保存候选人数据 /// </summary> /// <param name="entity ...
- 【Java】创建线程对象两种方式
1.继承Thread类,重载run方法: Thread t = new Thread(new Runnable() { @Override public void run() { // TODO Au ...
- 使用 dynamic 标记解析JSON字符串 JDynamic :支持Json反序列化为Dynamic对象
使用 dynamic 标记解析JSON字符串 http://www.cnblogs.com/taotaodetuer/p/4171327.html 1 string jsonStr = " ...
- JDynamic :支持Json反序列化为Dynamic对象
JDynamic :支持Json反序列化为Dynamic对象 2010年 .NET 4.0 发布前后,从3.5向4.0迁移,那时也有一些异构系统的需求,主要是和PHP打交道,通信使用的HTTP 格 ...
- 类对象序列化为json串,json串反序列化为类对象
1.类对象序列化为json串: 方法一: class P(object): def __init__(self,name,age,sex): self.name=name self.age=age s ...
随机推荐
- Python简单入门心得(一)
很久之前就对Python感兴趣了,但是一直没时间学习,最近两天还有点时间,于是网上看了下视频,Python不愧是强类型的编程语言,对每一行的缩进的都有很严格的要求,比如一个判断,如果条件语句else不 ...
- petite-vue源码剖析-双向绑定`v-model`的工作原理
前言 双向绑定v-model不仅仅是对可编辑HTML元素(select, input, textarea和附带[contenteditable=true])同时附加v-bind和v-on,而且还能利用 ...
- 微信小程序token失效 自动请求后端,适用于自动登录
app.js // app.js App({ onLaunch() { let token = wx.getStorageSync('token') if (!token) { wx.login({ ...
- OSPF协议原理及配置2-理解邻居和邻接关系
OSPF是一个动态路由协议,运行OSPF的路由器之间需要交换链路状态信息和路由信息,在交换这些信息之前首先需要建立邻接关系.邻接关系用来交换链路状态及路由信息. 注意:并非所有的邻居关系都可以成为邻接 ...
- LGP4001题解
题目大意 给定一张无向图,需要消耗代价才能使一条边被[数据删除],求使这张图不连通的最小代价. 一看就是最小割的应用啊... 从 \(u\) 到 \(v\),边权为 \(w\) 的边,建两条:一条从 ...
- test 分支强制替换master 分支的办法
test分支改动太多,并且master 分支好久没有改动.直接合并到master 分支的话,会产生很多冲突,几十个文件,修复冲突会花很多时间,并且是没有意义的.因此只能使用test 分支强制替换. 代 ...
- Linux的总线设备驱动模型
裸机编写驱动比较自由,按照手册实现其功能即可,每个人写出来都有很大不同: 而Linux中还需要按照Linux的驱动模型来编写,也就是需要按照"模板"来写,写出来的驱动就比较统一. ...
- AOP详解之三-创建AOP代理后记,创建AOP代理
AOP详解之三-创建AOP代理后记,创建AOP代理. 上篇文章已经获取到了AOP的信息,接下来就是拿着这些AOP的信息去创建代理了. 首先我们看下创建AOP代理的入口处. //这个方法将返回代理类 p ...
- 【网鼎杯2020青龙组】Web WriteUp
AreUSerialz 打开题目直接给出了源代码 <?php include("flag.php"); highlight_file(__FILE__); class Fil ...
- Python通过snap7库与西门子S7-1200建立S7通信,读写存储器数据,顺便写个流水灯
1.snap7 简介 snap7 是一个基于以太网与S7系列的西门子PLC通讯的开源库. 支持包括S7系列的S7-200.S7-200 Smart.S7-300.S7-400.S7-1200以及S7- ...