当前位置: 首页 > news >正文

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

虽然现在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,直接完成反序列化最终结果如下:

相关文章:

  • ubuntu20.04 安装cudnn
  • 单链表(3)
  • 成绩公布方式,这样操作更方便
  • 十三、W5100S/W5500+RP2040树莓派Pico<FTP Server>
  • ActiveMq学习⑨__基于zookeeper和LevelDB搭建ActiveMQ集群
  • 论文阅读:Ensemble Knowledge Transfer for Semantic Segmentation
  • 阿里云99元服务器2核2G3M带宽_4年396元_新老用户均可
  • VScode + opencv + c++ + win配置教程
  • 初识微服务技术栈
  • iOS 让界面元素的文字随着语言的更改而变化——本地化文字跟随
  • 如何在 Unbuntu 下安装配置 Apache Zookeeper
  • 一触即发!拓世法宝商业数字人一体机,化身数字员工,助你开拓连锁餐饮市场
  • 工程车云管家|叉车智能管家安卓主板方案
  • FPGA配置采集AR0135工业相机,提供2套工程源码和技术支持
  • 算法题:33. 搜索旋转排序数组(二分法)
  • 07.Android之多媒体问题
  • 2017年终总结、随想
  • Android开发 - 掌握ConstraintLayout(四)创建基本约束
  • CAP 一致性协议及应用解析
  • DOM的那些事
  • es6
  • Meteor的表单提交:Form
  • Spark学习笔记之相关记录
  • Terraform入门 - 1. 安装Terraform
  • uni-app项目数字滚动
  • WebSocket使用
  • 翻译:Hystrix - How To Use
  • 飞驰在Mesos的涡轮引擎上
  • 欢迎参加第二届中国游戏开发者大会
  • 技术胖1-4季视频复习— (看视频笔记)
  • 检测对象或数组
  • 简单易用的leetcode开发测试工具(npm)
  • 如何利用MongoDB打造TOP榜小程序
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 想使用 MongoDB ,你应该了解这8个方面!
  • 消息队列系列二(IOT中消息队列的应用)
  • Java数据解析之JSON
  • ​二进制运算符:(与运算)、|(或运算)、~(取反运算)、^(异或运算)、位移运算符​
  • ​渐进式Web应用PWA的未来
  • # Java NIO(一)FileChannel
  • #NOIP 2014# day.1 T2 联合权值
  • #在 README.md 中生成项目目录结构
  • (C)一些题4
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (NSDate) 时间 (time )比较
  • (带教程)商业版SEO关键词按天计费系统:关键词排名优化、代理服务、手机自适应及搭建教程
  • (非本人原创)我们工作到底是为了什么?​——HP大中华区总裁孙振耀退休感言(r4笔记第60天)...
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • (四)图像的%2线性拉伸
  • (原創) 如何將struct塞進vector? (C/C++) (STL)
  • (转)德国人的记事本
  • (转)项目管理杂谈-我所期望的新人
  • *上位机的定义
  • .gitignore
  • .net MVC中使用angularJs刷新页面数据列表