tnblog
首页
视频
资源
登录

开发winform xml文件生成C#类文件工具

8481人阅读 2020/5/25 12:38 总访问:144524 评论:1 收藏:1 手机
分类: C#

最近项目中用到了博通PLC采集图像数据保存的业务,需要解析软件返回的xml文件,然后保存到数据库。

为了方便就自己整了一个xml转换为对应实体类的一个工具,减少去对应xml一个个创建实体类的繁琐工作量。


先来个操作演示。

实体类:

原理:其实xml转换实体类就是xml节点对应实体类,规则如下:

  1. xml节点对应类;

  2. xml节点里面的属性,对应实体类的属性;

  3. xml子节点为xml父节点的属性;

  4. 如果一个节点的子节点数量不同,则已最多的一个为准进行创建类,如<result><label>Pass</label></result> 和 <result><label>Pass</label><id>0</id></result> 则以后面包含id的这个为准;

  5. 如果一个子节点在同一节点出现多次,则此节点在父节点上属性类型为List,反之一般为string(注意这里不能为IList,否则解析的时候会出问题,原因:List<T>是想创建一个List<T>的实例并且需要使用到List<T>的功能,进行相关操作;而IList<T>只是想创建一个基于接口IList<T>的对象的实例,只是这个接口是由List<T>实现的。所以它只是希望使用到IList<T>接口规定的功能而已。);

  6. 如果一个节点下面没有子节点也没有属性,则此节点只为父节点的属性,不用创建类。

  7. 类上标记[XmlRoot]特性,属性上标记[XmlAttribute],子节点上标记[XmlElement]。


一、创建一个Winform 工程,设计页面如下:

其中命名空间为生成实体类的命名空间。

窗体代码如下:

  1. using Newtonsoft.Json;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Data;
  6. using System.Drawing;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. using System.Windows.Forms;
  12. using System.Xml.Linq;
  13. using System.Xml.Serialization;
  14. namespace XmlFormApp
  15. {
  16.     public partial class Form1 : Form
  17.     {
  18.         public Form1()
  19.         {
  20.             InitializeComponent();
  21.         }
  22.         /// <summary>
  23.         /// 选择xml文件
  24.         /// </summary>
  25.         /// <param name="sender"></param>
  26.         /// <param name="e"></param>
  27.         private void iconTargetFilePath_Click(object sender, EventArgs e)
  28.         {
  29.             OpenFileDialog openFileDialog1 = new OpenFileDialog();
  30.             openFileDialog1.InitialDirectory = "c:\\";
  31.             openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
  32.             openFileDialog1.FilterIndex = 2;
  33.             openFileDialog1.RestoreDirectory = true;
  34.             if (openFileDialog1.ShowDialog() == DialogResult.OK)
  35.             {
  36.                 this.TargetFilePath.Text = openFileDialog1.FileName;
  37.                 this.richTextBox.Text = File.ReadAllText(openFileDialog1.FileName);
  38.                 this.iconButtonCreate.Enabled = true;
  39.                 this.iconButtonView.Enabled = true;
  40.             }
  41.         }
  42.         private void CreateClass(string path)
  43.         {
  44.             StringBuilder builder = new StringBuilder();
  45.             string classPath = "../../ClassFile.txt";
  46.             builder.Append(File.ReadAllText(classPath));
  47.             builder.Replace("{namespace}", textBoxClass.Text);
  48.             StringBuilder classTxt = new StringBuilder();
  49.             classTxt.Append($"\r\n\t/// <summary>\r\n\t///实体类\r\n\t/// </summary>");
  50.             try
  51.             {
  52.                 XElement element = XElement.Load(path);
  53.                 //子节点类集合
  54.                 List<string> classList = new List<string>();
  55.                 Dictionary<stringint> classAttrCountDic = new Dictionary<stringint>();
  56.                 foreach (var item in element.DescendantsAndSelf())
  57.                 {
  58.                     Dictionary<string, StringBuilder> itemDics = new Dictionary<string, StringBuilder>();
  59.                     var _calss = classList.Where(o => o == item.Name.ToString()).FirstOrDefault();
  60.                     var _classAttr = classAttrCountDic.Where(o => o.Key == item.Name.ToString() && o.Value != item.Elements().Count()).FirstOrDefault();
  61.                     StringBuilder classTxt1 = new StringBuilder();
  62.                     if (item.Elements().Count() == 0)
  63.                     {
  64.                         classList.Add(item.Name.ToString());
  65.                         if (_calss != null)
  66.                         {
  67.                             continue;
  68.                         }
  69.                         //如果此节点下没有属性则直接跳过
  70.                         if (item.Attributes().Count() == 0)
  71.                         {
  72.                             StringBuilder childTxt = new StringBuilder();
  73.                             childTxt.Append("\r\n\t\t[XmlElement(").Append($@"""{item.Name.ToString()}"")]");
  74.                             childTxt.Append($"\r\n\t\tpublic string {item.Name.ToString()}");
  75.                             childTxt.Append(" { get; set; }");
  76.                             classTxt1.Append("\r\n\t\t{").Append(item.Name.ToString()).Append("}");
  77.                             itemDics.Add(item.Name.ToString(), childTxt);
  78.                             continue;
  79.                         }
  80.                         //没有子节点了
  81.                         classTxt1.Append("\r\n\t[XmlRoot(").Append($@"""{item.Name.ToString()}"")]");
  82.                         classTxt1.Append($"\r\n\tpublic class {item.Name.ToString()}");
  83.                         classTxt1.Append("\r\n\t{");
  84.                         //classList.Add(item.Name.ToString());
  85.                         //创建该节点对应的属性
  86.                         if (item.Attributes().Count() > 0)
  87.                         {
  88.                             foreach (var itemAttr in item.Attributes())
  89.                             {
  90.                                 classTxt1.Append("\r\n\t\t[XmlAttribute(").Append($@"""{itemAttr.Name.ToString()}"")]");
  91.                                 classTxt1.Append($"\r\n\t\tpublic string {itemAttr.Name}");
  92.                                 classTxt1.Append(" { get; set; }");
  93.                             }
  94.                         }
  95.                         classTxt1.Append("\r\n\t}");
  96.                     }
  97.                     else
  98.                     {
  99.                         if (_calss != null)
  100.                         {
  101.                             if (_classAttr.Key != null)
  102.                             {
  103.                                 //返回先前创建类在字符串中的位置
  104.                                 int indexStr = classTxt.ToString().IndexOf($@"[XmlRoot(""{item.Name.ToString()}"")]");
  105.                                 StringBuilder itemStr = new StringBuilder();
  106.                                 itemStr.Append("\r\n\t");
  107.                                 itemStr.Append($@"[XmlRoot(""{item.Name.ToString()}"")]");
  108.                                 int i = 0;
  109.                                 while (true)
  110.                                 {
  111.                                     string lenStr = classTxt.ToString(indexStr + ($@"[XmlRoot(""{item.Name.ToString()}"")]").Length + i, 1);
  112.                                     i = i + 1;
  113.                                     itemStr.Append(lenStr);
  114.                                     if (itemStr.ToString().Contains("\r\n\t}"))
  115.                                     {
  116.                                         break;
  117.                                     }
  118.                                 }
  119.                                 classTxt.Replace(itemStr.ToString(), null);
  120.                                 classList.Remove(item.Name.ToString());
  121.                                 classAttrCountDic.Remove(item.Name.ToString());
  122.                             }
  123.                             else
  124.                             {
  125.                                 continue;
  126.                             }
  127.                         }
  128.                         classList.Add(item.Name.ToString());
  129.                         classAttrCountDic.Add(item.Name.ToString(), item.Elements().Count());
  130.                         //创建该节点对应的类
  131.                         classTxt1.Append("\r\n\t[XmlRoot(").Append($@"""{item.Name.ToString()}"")]");
  132.                         classTxt1.Append($"\r\n\tpublic class {item.Name.ToString()}");
  133.                         classTxt1.Append("\r\n\t{");
  134.                         //创建该节点子节点对应的类
  135.                         foreach (var itemElement in item.Elements())
  136.                         {
  137.                             StringBuilder childTxt = new StringBuilder();
  138.                             var itemElementDic = itemDics.Where(o => o.Key == itemElement.Name.ToString());
  139.                             if (itemElementDic.Count() > 0)
  140.                             {
  141.                                 childTxt.Append("\r\n\t\t[XmlElement(").Append($@"""{itemElement.Name.ToString()}"")]");
  142.                                 childTxt.Append($"\r\n\t\tpublic List<{itemElement.Name.ToString()}{itemElement.Name.ToString()}");
  143.                                 childTxt.Append(" { get; set; }");
  144.                                 itemDics.Remove(itemElement.Name.ToString());
  145.                                 itemDics.Add(itemElement.Name.ToString(), childTxt);
  146.                             }
  147.                             else
  148.                             {
  149.                                 if (itemElement.Elements().Count() == 0)
  150.                                 {
  151.                                     childTxt.Append("\r\n\t\t[XmlElement(").Append($@"""{itemElement.Name.ToString()}"")]");
  152.                                     childTxt.Append($"\r\n\t\tpublic string {itemElement.Name.ToString()}");
  153.                                     childTxt.Append(" { get; set; }");
  154.                                     classTxt1.Append("\r\n\t\t{").Append(itemElement.Name.ToString()).Append("}");
  155.                                     itemDics.Add(itemElement.Name.ToString(), childTxt);
  156.                                 }
  157.                                 else
  158.                                 {
  159.                                     childTxt.Append("\r\n\t\t[XmlElement(").Append($@"""{itemElement.Name.ToString()}"")]");
  160.                                     childTxt.Append($"\r\n\t\tpublic {itemElement.Name.ToString()} {itemElement.Name.ToString()}");
  161.                                     childTxt.Append(" { get; set; }");
  162.                                     classTxt1.Append("\r\n\t\t{").Append(itemElement.Name.ToString()).Append("}");
  163.                                     itemDics.Add(itemElement.Name.ToString(), childTxt);
  164.                                 }
  165.                             }
  166.                         }
  167.                         if (item.Name == "result")
  168.                         {
  169.                         }
  170.                         //创建该节点对应的属性
  171.                         if (item.Attributes().Count() > 0)
  172.                         {
  173.                             foreach (var itemAttr in item.Attributes())
  174.                             {
  175.                                 classTxt1.Append("\r\n\t\t[XmlAttribute(").Append($@"""{itemAttr.Name.ToString()}"")]");
  176.                                 classTxt1.Append($"\r\n\t\tpublic string {itemAttr.Name}");
  177.                                 classTxt1.Append(" { get; set; }");
  178.                             }
  179.                         }
  180.                         classTxt1.Append("\r\n\t}");
  181.                     }
  182.                     classTxt.Append(classTxt1);
  183.                     foreach (var itemDic in itemDics)
  184.                     {
  185.                         classTxt.Replace("{" + itemDic.Key + "}", itemDic.Value.ToString());
  186.                     }
  187.                 }
  188.                 //foreach (var itemDic in itemDics)
  189.                 //{
  190.                 //    classTxt.Replace("{" + itemDic.Key + "}", itemDic.Value.ToString());
  191.                 //}
  192.                 builder.Replace("{classTxt}", classTxt.ToString());
  193.                 this.richTextBox1.Text = builder.ToString();
  194.             }
  195.             catch (Exception ex)
  196.             {
  197.                 MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  198.             }
  199.         }
  200.         /// <summary>
  201.         /// 预览
  202.         /// </summary>
  203.         /// <param name="sender"></param>
  204.         /// <param name="e"></param>
  205.         private void iconButtonView_Click(object sender, EventArgs e)
  206.         {
  207.             string path = this.TargetFilePath.Text;
  208.             if (string.IsNullOrEmpty(textBoxClass.Text))
  209.             {
  210.                 MessageBox.Show("请输入命名空间""错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  211.                 return;
  212.             }
  213.             CreateClass(path);
  214.             iconButtonCheck.Enabled = true;
  215.         }
  216.         /// <summary>
  217.         /// 生成
  218.         /// </summary>
  219.         /// <param name="sender"></param>
  220.         /// <param name="e"></param>
  221.         private void iconButtonCreate_Click(object sender, EventArgs e)
  222.         {
  223.             try
  224.             {
  225.                 SaveFileDialog sfd = new SaveFileDialog();
  226.                 //设置文件类型 
  227.                 sfd.Filter = "类|*.cs";
  228.                 //设置默认文件类型显示顺序 
  229.                 sfd.FilterIndex = 1;
  230.                 //保存对话框是否记忆上次打开的目录 
  231.                 sfd.RestoreDirectory = true;
  232.                 //点了保存按钮进入
  233.                 if (sfd.ShowDialog() == DialogResult.OK)
  234.                 {
  235.                     string localFilePath = sfd.FileName.ToString(); //获得文件路径 
  236.                     string fileNameExt = localFilePath.Substring(localFilePath.LastIndexOf("\\") + 1); //获取文件名,不带路径
  237.                                                                                                        //创建写入文件
  238.                     FileStream fs1 = new FileStream(localFilePath, FileMode.Create, FileAccess.Write);
  239.                     StreamWriter sw = new StreamWriter(fs1);
  240.                     sw.WriteLine(this.richTextBox1.Text);//开始写入值
  241.                     sw.Close();
  242.                     fs1.Close();
  243.                     MessageBox.Show("生成成功""成功", MessageBoxButtons.OK, MessageBoxIcon.None);
  244.                 }
  245.             }
  246.             catch (Exception ex)
  247.             {
  248.                 MessageBox.Show("生成失败" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  249.             }
  250.         }
  251.         /// <summary>
  252.         /// 效验
  253.         /// </summary>
  254.         /// <param name="sender"></param>
  255.         /// <param name="e"></param>
  256.         private void iconButton1_Click(object sender, EventArgs e)
  257.         {
  258.             try
  259.             {
  260.                 var a = DeserializeToObject<root>(this.richTextBox.Text);
  261.                 string json = JsonConvert.SerializeObject(a);
  262.                 MessageBox.Show("效验成功""成功", MessageBoxButtons.OK, MessageBoxIcon.None);
  263.             }
  264.             catch (Exception ex)
  265.             {
  266.                 MessageBox.Show("效验失败" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  267.             }
  268.         }
  269.         /// <summary>
  270.         /// 将XML字符串反序列化为对象
  271.         /// </summary>
  272.         /// <typeparam name="T">对象类型</typeparam>
  273.         /// <param name="xml">XML字符</param>
  274.         /// <returns></returns>
  275.         public T DeserializeToObject<T>(string xml)
  276.         {
  277.             T myObject;
  278.             XmlSerializer serializer = new XmlSerializer(typeof(T));
  279.             StringReader reader = new StringReader(xml);
  280.             myObject = (T)serializer.Deserialize(reader);
  281.             reader.Close();
  282.             return myObject;
  283.         }
  284.         private void Form1_Resize(object sender, EventArgs e)
  285.         {
  286.             this.panel.Width = (this.panelCenter.Width - 20) / 2;
  287.             this.panel2.Width = (this.panelCenter.Width - 20) / 2;
  288.         }
  289.         private void Form1_Load(object sender, EventArgs e)
  290.         {
  291.             this.panel.Width = (this.panelCenter.Width - 20) / 2;
  292.             this.panel2.Width = (this.panelCenter.Width - 20) / 2;
  293.         }
  294.     }
  295. }


源代码地址:https://download.tnblog.net/resource/index/43db1228dbed4eb9904a4099f4e56e42


评价

剑轩

2020/5/25 23:38:01

这种工具有点nice,[嘻嘻][嘻嘻]感觉可以搞到web中来用,我下载来试试

微信<font Color='#ff5555'>开发三 使用反射根据消息类型自动调用不同方法

微信只会向我们一个地方推送消息,如果全部逻辑都写到一起,代码会非常多。所以我们可以考虑通过消息类型,来实现不同的消...

微信<font Color='#ff5555'>开发四 接受用户普通消息与回复消息

微信接收用户普通消息的文章可以在官方中直接看微信普通消息分类:接受用户文本消息 与 回复文本信息 注意在接收用户普通...

使用VS Code<font Color='#ff5555'>开发Python

Vs Code开发Python可以很好的支持代码调试、智能提示、代码对齐等1:下载VS Codehttps://code.visualstudio.com/Downloadvs ...

使用AppCan<font Color='#ff5555'>开发app之Color='#ff5555'>开发流程介绍

目前 App的开发主要包含三种方式:原生开发、H5开发、混合开发大概列举一下3种模式优缺点:原生:原生应用由于利用的是官方...

<font Color='#ff5555'>开发自己的代码生成工具

在一个项目中其实有很多代码都是重复的,几乎每个基础模块的代码都有增删改查的功能,而这些功能都是大同小异,如果这些功...

vue.js 学习日记第一章-安装vue<font Color='#ff5555'>开发环境

官网:https://cn.vuejs.org/v2/guide/ 这是一篇学习性文章,不定时更新,用来记录我学习vue.js的过程。 首先,是v...

.net 微信<font Color='#ff5555'>开发获取aCCess_token使用缓存处理token过期

获取access_token很简单,使用httpclient发起一个请求就可以了,我们使用redis做一下缓存处理publicstaticstringGetToken()...

01-后端<font Color='#ff5555'>开发的-MVC-与前端<font Color='#ff5555'>开发-MVVM-之间的区别

现在网站开发一般都是前台页面与后台的数据交互相互分离的状态,两者之间可以使用 Ajax 远程发送和响应数据,[注意:当然也不...

vs2019<font Color='#ff5555'>开发net Core3.x修改视图页面后,刷新浏览器看不到修改后的效果

一:安装依赖包Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation NuGet 包。Install-PackageMicrosoft.AspNetCore.Mvc.R...

微信公众<font Color='#ff5555'>开发token的获取和Redis缓存结合用

创建一个类库DTO_Token_Tools,在创建一个工具类在工具类里面写一个access_Token_Tool()方法//获取token publicstringacce...

多模块<font Color='#ff5555'>开发

通常项目中,需要把项目分层。通常分为po(模型层)、dao(数据访问层)、service(业务逻辑层)、web(表现层)。以前分层...

微信公众号网页<font Color='#ff5555'>开发获取OpenID

如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑微信官方...

前端、Cordova安卓、iOS<font Color='#ff5555'>开发,全自学 一个星期多时间累死我了,撑过来了

前言自学前端之路:不知不觉出来工作已经快一个月了,给你们分享一下状况正文最近公司用的项目是ionic框架开发不得不自学哇...

ReaCt前端<font Color='#ff5555'>开发环境搭建

(一) 安装Node.js,具体步骤如下首先,我们需要安装Node.js,直接搜索并在官网下载安装包Node.js官网:https://nodejs.org/...

Cordova<font Color='#ff5555'>开发禁止软键盘弹出

前 言tnblog 随着HTML5的不断发展,移动开发成为主流趋势!越来越多的公司开始选择使用HTML5开发手机APP,而随着手机硬件...
Decorating heart
排名
22
文章
14
粉丝
21
评论
27
腾讯防水墙
赖成龙 : 学长你有下载好的js文件吗
使用 JSON WEB TOKEN (jwt) 验证
饰心 : 由于最近换了新的工作环境,还在挖煤中。后续会增加博客更新频率。
腾讯防水墙
饰心 : @剑轩,快去给tnblog弄一个
使用select2实现下拉框中显示图片
剑轩 : 秀啊.....,飞常不错
使用select2实现下拉框中显示图片
饰心 : 嗯~刚好差不多下班
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术
我躺在黑暗里用血丝赤红的眼看每一个凌晨的灿红初阳。