C#解析XML并反序列化为Model的方法

news/2025/1/8 1:12:06/

虽然现在json大行其道,但是xml格式依旧占据着广阔的编程世界,不管光伏锂电激光卫星汽车等等工业领域,基本上都是以xml为主,广大的.NET开发人员有很多被xml折磨的都要转java了,这篇小作文就来玩一种迅速完成xml到model的过程,让老板交代的任务能在5分钟解决,真正实现上班5分钟,摸鱼7小时。

本次要解析的XML格式如下:

<?xml version="1.0" encoding="UTF-8"?>
<GCS Version="0x100"><ProjectInfo CfgUUID="5f2acfd0-aa91-49bb-a6d3-8f994810ffd5" ReduFlag="YES" UcpProtocol="1"ControllerType="33280" ProjectName="5201rddcwx" IPADDRA="172.20.1.2" IPADDRB="172.21.1.2" /><MemInfo><Area Size="131072" Index="0" Name="A" /><Area Size="131072" Index="1" Name="B" /></MemInfo><TagList><Tag Index="0" Name="MODULE1_TCPCmd0_VAR_OUT" Desc="" BitOffset="0" Offset="0"DataType="MODBUS_DT0" InitValue="OFF" AccessRight="ReadWrite" /><Tag Index="0" Name="MODULE1_TCPCmd1_VAR" Desc="" BitOffset="0" Offset="80"DataType="MODBUS_DT4" InitValue="OFF" AccessRight="ReadWrite" /></TagList><TagListSafety><Tag Index="0" Name="MODULE1_TCPCmd0_VAR_OUT" Desc="" UCPINDEX="2" BitOffset="0" Offset="0"DataType="INT" InitValue="OFF" AccessRight="ReadWrite" /><Tag Index="0" Name="MODULE1_TCPCmd1_VAR" Desc="" UCPINDEX="2" BitOffset="0" Offset="80"DataType="DWORD" InitValue="OFF" AccessRight="ReadWrite" /></TagListSafety><DataTypeList><Struct Size="4" Name="COM5002TCP_D" Desc=""><Element Name="DEVCFGSTATE" Desc="描述描述" BitOffset="1" Offset="0" DataType="BOOL" /><Element Name="DEVTYPESTATE" Desc="描述描述" BitOffset="2" Offset="0"DataType="BOOL" /><Element Name="COMMSTATE" Desc="描述描述" BitOffset="3" Offset="0" DataType="BOOL" /></Struct><Struct Size="40" Name="COM5002TCP_IN" Desc=""><Element Name="DEVCFGSTATE" Desc="描述描述" BitOffset="7"Offset="0" DataType="BOOL" /></Struct><Struct Size="128" Name="GCU5201_D" Desc=""><Element Name="KeyMode" Desc="描述描述" BitOffset="0" Offset="78" DataType="BYTE" /><Element Name="TIME" Desc="描述描述" BitOffset="0" Offset="0" DataType="TIME_FMT"><Element Name="TIME.YEAR" Desc="描述描述" BitOffset="0" Offset="0" DataType="BYTE" /><Element Name="TIME.MONTH" Desc="描述描述" BitOffset="0" Offset="1" DataType="BYTE" /></Element><Element Name="TimeServerDiag" Desc="描述描述" BitOffset="0" Offset="16"DataType="BYTE" /></Struct><Struct Size="24" Name="MODBUS_DT0" Desc=""><Element Name="VAR0" Desc="" BitOffset="0" Offset="12" DataType="INT" /><Element Name="VAR1" Desc="" BitOffset="0" Offset="14" DataType="INT" /><Element Name="VAR2" Desc="" BitOffset="0" Offset="16" DataType="INT" /><Element Name="VAR3" Desc="" BitOffset="0" Offset="18" DataType="INT" /><Element Name="VAR4" Desc="" BitOffset="0" Offset="20" DataType="INT" /></Struct><Struct Size="12" Name="MODBUS_DT2" Desc=""><Element Name="CommState" Desc="描述描述" BitOffset="4" Offset="0" DataType="BOOL" /></Struct><Struct Size="208" Name="MODBUS_DT4" Desc=""><Element Name="VAR0" Desc="" BitOffset="0" Offset="8" DataType="INT" /></Struct><Struct Size="4" Name="POINTER" Desc="" /><Struct Size="8" Name="TIME_FMT" Desc="STR_GC_CI_DATATYPE_TIME_FMT_DESC"><Element Name="YEAR" Desc="骞" BitOffset="0" Offset="0" DataType="BYTE" /></Struct><Struct Size="64" Name="_SEND_CMD" Desc=""><Element Name="pIN" Desc="STR_SC_AUX_SEND_CMD_INPUT_pIN" BitOffset="0" Offset="0"DataType="DWORD" /></Struct><Array Size="256" Name="GCU5201_D[2]" ElementDataType="GCU5201_D" ElementNum="2" /></DataTypeList>
</GCS>

可以看到本次的xml都是XmlAttribute,此处可以借助 System.Xml这个类进行操作,先新建所有类:
 

 [XmlRoot("GCS")]public class SuperConGCSInfo{[XmlElement("ProjectInfo")]public ProjectInfo ProInfo { get; set; }[XmlArray("MemInfo")][XmlArrayItem("Area")]public MemInfo[] MemInfos { get; set; }[XmlArray("TagList")][XmlArrayItem("Tag")]public Tags[] TagList { get; set; }[XmlArray("TagListSafety")][XmlArrayItem("Tag")]public Tags[] TagListSafety { get; set; }[XmlElement("DataTypeList")]public DataTypeList DataTypeList { get; set; }}public class DataTypeList{[XmlElement("Struct")]public Struct[] Struct { get; set; }[XmlElement("Array")]public Arrays[] Arrays { get; set; }}public class Arrays{[XmlAttribute("Size")]public string Size { get; set; }[XmlAttribute("Name")]public string Name { get; set; }[XmlAttribute("ElementDataType")]public string ElementDataType { get; set; }[XmlAttribute("ElementNum")]public string ElementNum { get; set; }}public class ProjectInfo{[XmlAttribute("CfgUUID")]public string CfgUUID { get; set; }[XmlAttribute("ReduFlag")]public string ReduFlag { get; set; }[XmlAttribute("UcpProtocol")]public string UcpProtocol { get; set; }[XmlAttribute("ControllerType")]public string ControllerType { get; set; }[XmlAttribute("ProjectName")]public string ProjectName { get; set; }[XmlAttribute("IPADDRA")]public string IPADDRA { get; set; }[XmlAttribute("IPADDRB")]public string IPADDRB { get; set; }}public class MemInfo{[XmlAttribute("Size")]public string Size { get; set; }[XmlAttribute("Index")]public string Index { get; set; }[XmlAttribute("Name")]public string Name { get; set; }}public class Tags{[XmlAttribute("Index")]public string Index { get; set; }[XmlAttribute("Name")]public string Name { get; set; }[XmlAttribute("Desc")]public string Desc { get; set; }[XmlAttribute("BitOffset")]public string BitOffset { get; set; }[XmlAttribute("Offset")]public string Offset { get; set; }[XmlAttribute("DataType")]public string DataType { get; set; }[XmlAttribute("InitValue")]public string InitValue { get; set; }[XmlAttribute("AccessRight")]public string AccessRight { get; set; }}public class Struct{[XmlAttribute("Size")]public string Size { get; set; }[XmlAttribute("Name")]public string Name { get; set; }[XmlElement("Element")]public Element[] Elements { get; set; }}public class Element{[XmlAttribute("Name")]public string Name { get; set; }[XmlAttribute("Desc")]public string Desc { get; set; }[XmlAttribute("BitOffset")]public string BitOffset { get; set; }[XmlAttribute("Offset")]public string Offset { get; set; }[XmlAttribute("DataType")]public string DataType { get; set; }[XmlElement("Element")]public Element[] Elements { get; set; }}

说明一下这里面的一些特性。

根节点(XmlRoot):

        首先类中包含根节点(XmlRoot)GCS,跟节点是xml中最外层的包裹元素,C#中使用XmlRoot特性声明;


元素节点(XmlElement)

        xml中任何一个节点,不知道怎么生命,其实都可以使用XmlElement,它是万能的。比如我们上面xml看到的ProjectInfo、DataTypeList等等包裹的节点都是;

数组(XmlArray):

        数组节点一般情况下都是和XmlArrayItem搭配使用,比如MemInfo是数组,那XmlArrayItem就是Area,TagList对应的是Tag,TagListSafety对应也是Tag,这样一声明就非常清晰。c#中数组使用XmlArray、子类使用XmlArrayItem声明。

        以上xml我们需要注意的是DataTypeList这个节点,DataTypeList可以使用XmlArray进行声明,但是如果一旦这样声明,就会导致Array读取失败,所以我这边单独又新建一个类DataTypeList,DataTypeList类里面又分别使用XmlElement声明一个Struct和Array,这样下去,就能正常读取了。

        其实System.Xml里面有非常多的特性,比如枚举(XmlEnum),忽略(XmlIgnore)、包含(XmlInclude),纯文本(XmlText)、抽象类型(XmlType)等等,但是基本上不在特殊场合基本上用不到,其余的可以自行新建xml试试。

新建读取xml方法:

 public T DeserializeFromXml<T>(string filePath){try{using (StreamReader reader = new StreamReader(filePath, Encoding.UTF8)){XmlSerializer xs = new XmlSerializer(typeof(T));T ret = (T)xs.Deserialize(reader);return ret;}}catch{return default(T);}}

使用文件上传方式读取xml:
 

 var dialog = new OpenFileDialog{DefaultExt = "*.xml",AddExtension = true,Filter = "Import Files|*.xml",CheckPathExists = true};
if (dialog.ShowDialog() != true || string.IsNullOrEmpty(dialog.FileName) || !File.Exists(dialog.FileName))return;
SuperConGCSInfo beckhoffTagModel = superConVarConver.DeserializeFromXml<SuperConGCSInfo>(dialog.FileName);

以上方法读取xml速度块,能迅速生成一个Model,直接完成反序列化最终结果如下:


http://www.ppmy.cn/news/1208697.html

相关文章

PHP安全问题:远程溢出、DoS、safe_mode绕过漏洞

一、Web 服务器安全 PHP 其实不过是 Web服务器的一个模块功能,所以首先要保证 Web服务器的安全。当 然 Web服务器要安全又必须是先保证系统安全,这样就扯远了, 无穷无尽。PHP可以和各种 Web 服务器结合,这里也只讨论 Apache。非常建议以 chroot 方式安装启动 Apache,这样…

C++之旅(学习笔记)第3章 模块化

C之旅&#xff08;学习笔记&#xff09;第3章 模块化 3.1 分离编译 C支持一种名为分离编译的概念&#xff0c;用户代码只能看见所用类型和函数的声明。 有两种方法可以实现它&#xff1a; 头文件&#xff1a;将声明放进一个名为头文件的独立文件&#xff0c;然后将头文件以…

类直径树上贪心

http://cplusoj.com/d/senior/p/SS231109C 场上想到枚举点&#xff0c;然后最大值为高&#xff0c;然后可以求最大值。但是感觉计数会重 计数其实不会重&#xff0c;如图中&#xff0c;红色线段显然比蓝色线段优 所以我们枚举3叉点时没错的 #include<bits/stdc.h> usin…

利用AI快速跨过新手区:用DevChat编写Python程序-CSV导入TDengine

还在用百度搜索编程吗&#xff1f; 直接上 AI&#xff0c;帮助小白快速跨过新手区。 以下用一个物联网最常见的场景做示例演示如何利用 AI 快速编程。 ChatGPT4 是目前最火的 AI 了&#xff0c;但是国内却用不了。不过现在新出的 DevChat 可以让大家尝鲜一番。 以下介绍来自B…

竞赛 题目: 基于深度学习的疲劳驾驶检测 深度学习

文章目录 0 前言1 课题背景2 实现目标3 当前市面上疲劳驾驶检测的方法4 相关数据集5 基于头部姿态的驾驶疲劳检测5.1 如何确定疲劳状态5.2 算法步骤5.3 打瞌睡判断 6 基于CNN与SVM的疲劳检测方法6.1 网络结构6.2 疲劳图像分类训练6.3 训练结果 7 最后 0 前言 &#x1f525; 优…

物奇平台耳机宕机恢复功能实现

是否需要申请加入数字音频系统研究开发交流答疑群(课题组)&#xff1f;可加我微信hezkz17, 本群提供音频技术答疑服务&#xff0c;群赠送语音信号处理降噪算法&#xff0c;蓝牙音频&#xff0c;DSP音频项目核心开发资料, 物奇平台耳机宕机恢复功能实现 一 需求与场景 1 使…

Ubuntu安装.Net SDK

参考微软文档&#xff1a;在 Linux 上安装 .NET选择自己对应系统版本的链接辅助即可。 我这里使用的是 Ubuntu 20.04&#xff0c;因为在这个版本.Net 在Ubuntu包源存储库中不可用&#xff0c;需要手动添加Microsoft包存储库。 使用 APT 进行安装可通过几个命令来完成。 安装 …

【23真题】简单!原题很多!211!

今天分享的是23年内蒙古869的信号与系统试题及解析。 本套试卷难度分析&#xff1a;22年内蒙古大学869考研真题&#xff0c;若有需要&#xff0c;戳这里自取&#xff01;该院校是考察通信原理信号的&#xff0c;从信号部分来看&#xff0c;本套试题内容难度中等偏下&#xff0…