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 ...
随机推荐
- 【故障公告】龙卷风来袭:突增的并发请求,撑不住的CPU
(上图是数据库连接数监控图) 非常抱歉,今天下午 16:50-17:40 期间,一场龙卷风突袭园子,突增的并发请求狂卷博客站点的 pod,由于风力巨大(70%左右的增量),pod 的 cpu 不堪重负 ...
- LGB+XGB+CNN一般写法
现在的比赛,想要拿到一个好的名次,就一定要进行模型融合,这里总结一下三种基础的模型: - lightgbm:由于现在的比赛数据越来越大,想要获得一个比较高的预测精度,同时又要减少内存占用以及提升训练速 ...
- m3u8文件合并处理
m3u8文件合并处理 简介 M3U8 是 Unicode 版本的 M3U,用 UTF-8 编码."M3U" 和 "M3U8" 文件都是苹果公司使用的 HTTP ...
- OpenCv基础_一
图片的读取和展示 import cv2 img = cv2.imread('1.jpg') cv2.imshow('img',img) cv2.waitKey(0) cv2.destroyAllWin ...
- Mybatis中Log4j日志的使用
参考资料: (1). 百度百科:https://baike.baidu.com/item/log4j/480673?fr=aladdin (2). B站狂神的视频:https://www.bilibi ...
- SQL存储过程的学习01
虽工作多年,但是sql的存储过程一致都没怎么用过,今天来按照博客https://www.cnblogs.com/applelife/p/11016674.html来学习一下(我使用postgre sq ...
- [happyctf]部分writeup
题目名称:sqltest所属:MISC考察点:盲注 眼力 耐心(好吧是废话) 附件下载下来 ,到手一个流量包,用wireshark打开,大致浏览了一下,抓的应该是盲注的数据流量. 这里有一个经验问题, ...
- GitHub如何选择合适的license(许可证)
license译为许可证,也可作为开源协议,它可以将自己创作的东西,授权给他人使用,并约定了使用者可以有的权利和必须遵从的义务.现在很多优秀的开源项目都有设置license,不同的license所约束 ...
- Spring两种注入方式
1.XML注入 2.标签注入
- 数据结构-二叉树、B树、B+树、B*树(整理版)
1. 二叉树 二叉树的特点: ① 所有非叶子节点至多拥有两个儿子(Left和Right): ② 所有节点存储一个关键字: ③ 非叶子节点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树: ...