『7x24小时有问必答』

C# 上位机 XML 数据导入导出

适配 WinForm/WPF,极简可直接复用,兼顾工控数据结构化 + 容错性

核心方案(2 种常用)

方案 1:XmlSerializer(推荐,工控结构化数据首选)

优点:强类型、易维护,适配 PLC 参数 / 设备配置 / 生产记录等结构化数据

1. 先定义实体类(工控示例)

// 必须加[Serializable],属性需带get/set[Serializable]public  class  DeviceConfig    // 工控设备配置,可直接改字段适配你的场景{       public  string  DeviceName {  get;  set; }  // 设备名称       public  int  PLCAddress {  get;  set; }      // PLC地址       public  int  BaudRate {  get;  set; }         // 波特率       public  List<channelparam> Channels {  get;  set; }  // 通道参数(集合)}[Serializable]public  class  ChannelParam{       public  string  ChannelName {  get;  set; }       public  float  UpperLimit {  get;  set; }   // 上限       public  float  LowerLimit {  get;  set; }   // 下限}

2. 导出 XML(一键保存)

///  <summary>///  XML导出(带异常处理,工控场景防丢数据)///  </summary>///  <param name="data">要保存的实体数据///  <param name="filePath">保存路径(如D:\设备配置.xml)public  bool  ExportToXml<T>(T data,  string  filePath){       try      {             // 创建目录,避免路径不存在报错             var  dir = Path.GetDirectoryName(filePath);             if  (!Directory.Exists(dir)) Directory.CreateDirectory(dir);             var  serializer =  new  XmlSerializer(typeof(T));             using  (var  fs =  new  FileStream(filePath, FileMode.Create, FileAccess.Write))            {                  serializer.Serialize(fs, data);            }             return  true;      }       catch  (Exception ex)      {            MessageBox.Show($"导出失败:{ex.Message}");//上位机弹窗提示             return  false;      }}// 调用示例(上位机按钮点击事件)private  void  btnExport_Click(object  sender, EventArgs e){       // 构造测试数据(实际替换为你的业务数据)       var  config =  new  DeviceConfig      {            DeviceName =  "流水线机器人1号",            PLCAddress =  1,            BaudRate =  9600,            Channels =  new  List<channelparam>            {                   new  ChannelParam{ChannelName="温度",UpperLimit=80,LowerLimit=20},                   new  ChannelParam{ChannelName="压力",UpperLimit=1.0f,LowerLimit=0.2f}            }      };       // 选择保存路径       using  (var  sfd =  new  SaveFileDialog())      {            sfd.Filter =  "XML文件|*.xml";             if  (sfd.ShowDialog() == DialogResult.OK)            {                  ExportToXml(config, sfd.FileName);            }      }}

3. 导入 XML(一键读取)

///  <summary>///  XML导入(强类型解析,直接绑定业务数据)///  </summary>public  T  ImportFromXml<T>(string  filePath)  where  T :  class{       try      {             if  (!File.Exists(filePath))  return  null;             var  serializer =  new  XmlSerializer(typeof(T));             using  (var  fs =  new  FileStream(filePath, FileMode.Open, FileAccess.Read))            {                   return  serializer.Deserialize(fs)  as  T;            }      }       catch  (Exception ex)      {            MessageBox.Show($"导入失败:{ex.Message}");             return  null;      }}// 调用示例(按钮点击)private  void  btnImport_Click(object  sender, EventArgs e){       using  (var  ofd =  new  OpenFileDialog())      {            ofd.Filter =  "XML文件|*.xml";             if  (ofd.ShowDialog() == DialogResult.OK)            {                   var  config = ImportFromXml<deviceconfig>(ofd.FileName);                   if  (config !=  null)                  {                         // 绑定到上位机界面控件(示例)                        txtDeviceName.Text = config.DeviceName;                        txtPLCAddr.Text = config.PLCAddress.ToString();                         // 集合数据绑定到DataGridView                        dgvChannels.DataSource = config.Channels;                  }            }      }}

方案 2:XDocument(灵活,适配非结构化 / 动态 XML)

适合字段不固定的场景(如临时日志、自定义参数)

导出 + 导入示例

// 导出public  void  ExportXmlByXDoc(string  filePath){       var  doc =  new  XDocument(             new  XDeclaration("1.0",  "UTF-8",  "yes"),             new  XElement("DeviceConfig",                   new  XElement("DeviceName",  "流水线机器人1号"),                   new  XElement("PLCAddress",  1),                   new  XElement("Channels",                         new  XElement("Channel",                               new  XElement("Name",  "温度"),                               new  XElement("Upper",  80)                        )                  )            )      );      doc.Save(filePath);}// 导入public  void  ImportXmlByXDoc(string  filePath){       if  (!File.Exists(filePath))  return;       var  doc = XDocument.Load(filePath);       // 读取节点       var  devName = doc.Element("DeviceConfig").Element("DeviceName").Value;       var  plcAddr =  int.Parse(doc.Element("DeviceConfig").Element("PLCAddress").Value);}

工控场景关键优化(必加)

编码统一:指定UTF-8,避免中文乱码(XmlSerializer 默认 UTF-8,XDocument 需手动声明)。
路径选择:固定上位机默认路径(如Application.StartupPath + "/Config/"),方便部署。
异常处理:必须捕获 IO / 序列化异常,避免上位机闪退。
版本兼容:实体类新增字段加[XmlIgnore](可选字段),兼容旧 XML 文件。
权限处理:工控机常无管理员权限,避免保存到 C 盘根目录,优先选软件目录 / 桌面。
[XmlIgnore]  // 新增字段不序列化,不影响旧文件导入public  string  NewField {  get;  set; }

引用 & 注意

必加命名空间(不用额外 NuGet,原生支持)。
using  System.Xml;using  System.Xml.Serialization;using  System.Xml.Linq;using  System.IO;
实体类注意:不能是抽象类,属性必须有get/set,否则序列化失败。
大文件适配:工控大批量数据(如生产日志),用XmlReader/XmlWriter流式读写,不占内存。

</deviceconfig></channelparam></channelparam>

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

上一主题上一主题         下一主题下一主题
QQ手机版小黑屋粤ICP备17165530号

关于我们·投诉举报· 用户帮助· 联系我们 · 本站服务 · 版权声明· 隐私政策 · 投搞指南

法律保护:PLC技术网,plcjs.com,plcjs.net等字样
Copyright 2010-2030. All rights reserved. 


微信公众号二维码 抖音二维码 百家号二维码 今日头条二维码哔哩哔哩二维码