使用 C# 对象将 WinRiver 项目文件进行 XML 序列化和反序列化的实例详解
一、序列化和反序列化的目的
1、以对象编程,简化程序代码。
2、以对象编程,对程序配置文件实施简单的读写。
二、WinRiver 的项目 MMT 文件架构示例
WinRiver 的项目 MMT 文件,是 RDI ADCP 的测量项目记录,包含很多设置。
<?xml version="1.0" encoding="UTF-8"?>
<WinRiver>
<Project Name="xhz20240806_22.mmt" Version="1.0.0.2" Flags="0">
<Locked>False</Locked>
<Site_Information Type="1" Checked="1" Status="0" Error="0">
<Agency>汉口分局</Agency>
<Country>中国</Country>
<State>湖北</State>
<County>武汉</County>
<!-- 从此处开始省略其余内容信息 -->
</Site_Information>
<Site_Discharge Type="2" Checked="1" Status="0" Error="0">
<Transect Type="5" Checked="1" Status="0" SelectAll="1" First="0" Last="0" Error="0">
<File PathName="F:\XHZ20240806_22\XHZ20240806_22_000_24-08-06.PD0" Type="6" TransectNmb="0">XHZ20240806_22_000_24-08-06.PD0</File>
<File PathName="F:\XHZ20240806_22\XHZ20240806_22_000_24-08-06_ASC.TXT" Type="14" TransectNmb="0">XHZ20240806_22_000_24-08-06_ASC.TXT</File>
<File PathName="F:\XHZ20240806_22\XHZ20240806_22_000_24-08-06_EH.TXT" Type="13" TransectNmb="0">XHZ20240806_22_000_24-08-06_EH.TXT</File>
<File PathName="F:\XHZ20240806_22\XHZ20240806_22_000_24-08-06_GPS.TXT" Type="11" TransectNmb="0">XHZ20240806_22_000_24-08-06_GPS.TXT</File>
<Configuration Type="7" Checked="0" Status="-1" Error="0">
<Commands>
<!-- 省略其余内容信息 -->
</Commands>
<Depth_Sounder>
<!-- 从此处开始省略其余信息 -->
</Depth_Sounder>
<Ext_Heading>
<!-- 从此处开始省略其余信息 -->
</Ext_Heading>
<GPS>
<!-- 从此处开始省略其余信息 -->
</GPS>
<Discharge>
<!-- 从此处开始省略其余信息 -->
</Discharge>
<Edge_Estimates>
<!-- 从此处开始省略其余信息 -->
</Edge_Estimates>
<Offsets>
<!-- 从此处开始省略其余信息 -->
</Offsets>
<Processing>
<!-- 从此处开始省略其余信息 -->
</Processing>
<Recording>
<!-- 从此处开始省略其余信息 -->
</Recording>
<Wizard_Info>
<!-- 从此处开始省略其余信息 -->
</Wizard_Info>
<DMFilter>
<!-- 从此处开始省略其余信息 -->
</DMFilter>
</Configuration>
<Configuration Type="7" Checked="1" Status="1" Error="0">
<Commands>
<!-- 省略其余内容信息 -->
</Commands>
<Depth_Sounder>
<!-- 从此处开始省略其余信息 -->
</Depth_Sounder>
<Ext_Heading>
<!-- 从此处开始省略其余信息 -->
</Ext_Heading>
<GPS>
<!-- 从此处开始省略其余信息 -->
</GPS>
<Discharge>
<!-- 从此处开始省略其余信息 -->
</Discharge>
<Edge_Estimates>
<!-- 从此处开始省略其余信息 -->
</Edge_Estimates>
<Offsets>
<!-- 从此处开始省略其余信息 -->
</Offsets>
<Processing>
<!-- 从此处开始省略其余信息 -->
</Processing>
<Recording>
<!-- 从此处开始省略其余信息 -->
</Recording>
<Wizard_Info>
<!-- 从此处开始省略其余信息 -->
</Wizard_Info>
<DMFilter>
<!-- 从此处开始省略其余信息 -->
</DMFilter>
</Configuration>
</Transect>
<Transect Type="5" Checked="1" Status="0" SelectAll="1" First="100" Last="200" Error="0">
<!-- 从此处开始省略其余信息 -->
</Transect>
<Discharge_Summary>
<!-- 从此处开始省略其余信息 -->
</Discharge_Summary>
</Site_Discharge>
<QA_QC Type="3" Checked="1" Status="0" Error="0">
<!-- 从此处开始省略其余信息 -->
</QA_QC>
<Collect_Data Type="4" Checked="1" Status="0" Error="0">
<!-- 从此处开始省略其余信息 -->
</Collect_Data>
<DisplaySettings>
<Globals>
<Depth_Max>18.000000</Depth_Max>
</Globals>
</DisplaySettings>
</Project>
</WinRiver>
三、以 WinRiver 为对象进行 C# 代码编程
创建新的类,命名为 WinRiverXML。
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
namespace 命名空间
{
public class WinRiverXML
{
//将 3.1 - 3.8 的代码内容放入
}
}
3.1 声明 WinRiver 对象
/// <summary>WinRiver根目录</summary>
[XmlRoot("WinRiver")]
public class WinRiver
{
/// <summary>项目</summary>
[XmlElement("Project")]
public Project Project { get; set; }
}
3.2 声明 Project 对象
/// <summary>项目</summary>
public class Project
{
/// <summary>名称属性</summary>
[XmlAttribute("Name")]
public string Name { get; set; } = "Text.mmt";
/// <summary>版本属性</summary>
[XmlAttribute("Version")]
public string Version { get; set; } = "1.0.0.2";
/// <summary>标志属性</summary>
[XmlAttribute("Flags")]
public string Flags { get; set; } = "0";
/// <summary>锁定标志</summary>
[XmlElement("Locked")]
public string Locked { get; set; } = "False";
/// <summary>测站信息</summary>
[XmlElement("Site_Information")]
public Site_Information Site_Information { get; set; }
/// <summary>测站流量</summary>
[XmlElement("Site_Discharge")]
public Site_Discharge Site_Discharge { get; set; }
/// <summary>质量控制</summary>
[XmlElement("QA_QC")]
public QA_QC QA_QC { get; set; }
/// <summary>采集数据</summary>
[XmlElement("Collect_Data")]
public Collect_Data Collect_Data { get; set; }
/// <summary>显示设置</summary>
[XmlElement("DisplaySettings")]
public DisplaySettings DisplaySettings { get; set; }
}
3.3 声明 Site_Information 对象
/// <summary>测站信息</summary>
public class Site_Information
{
/// <summary>类型</summary>
[XmlAttribute("Type")]
public string Type { get; set; } = "1";
/// <summary>复选</summary>
[XmlAttribute("Checked")]
public string Checked { get; set; } = "1";
/// <summary>类型</summary>
[XmlAttribute("Status")]
public string Status { get; set; } = "0";
/// <summary>错误</summary>
[XmlAttribute("Error")]
public string Error { get; set; } = "0";
/// <summary>测验单位</summary>
public string Agency { get; set; }
/// <summary>国家</summary>
public string Country { get; set; }
/// <summary>省</summary>
public string State { get; set; }
/// <summary>市</summary>
public string County { get; set; }
//省略其它信息代码
}
3.4 声明 Site_Discharge 对象
/// <summary>测站流量</summary>
public class Site_Discharge
{
/// <summary>类型</summary>
[XmlAttribute("Type")]
public string Type { get; set; } = "2";
/// <summary>复选</summary>
[XmlAttribute("Checked")]
public string Checked { get; set; } = "1";
/// <summary>状态</summary>
[XmlAttribute("Status")]
public string Status { get; set; } = "0";
/// <summary>错误</summary>
[XmlAttribute("Error")]
public string Error { get; set; } = "0";
/// <summary>断面测回</summary>
[XmlElement("Transect")]
public List<Transect> Transect { get; set; }
/// <summary>断面流量汇总</summary>
[XmlElement("Discharge_Summary")]
public Discharge_Summary Discharge_Summary { get; set; }
}
3.5 声明 QA_QC 、Collect_Data 、DisplaySettings 对象
/// <summary>质量控制</summary>
public class QA_QC
{
//省略其它内容代码
}
/// <summary>采集数据</summary>
public class Collect_Data
{
//省略其它内容代码
}
/// <summary>显示设置</summary>
public class DisplaySettings
{
//省略其它内容代码
}
3.6 声明 Transect 、 Discharge_Summary 、File 、Configuration 对象
/// <summary>断面</summary>
public class Transect
{
/// <summary>类型</summary>
[XmlAttribute("Type")]
public string Type { get; set; } = "5";
/// <summary>复选</summary>
[XmlAttribute("Checked")]
public string Checked { get; set; } = "1";
/// <summary>状态</summary>
[XmlAttribute("Status")]
public string Status { get; set; } = "0";
/// <summary>全选</summary>
[XmlAttribute("SelectAll")]
public string SelectAll { get; set; } = "1";
/// <summary>第一集合</summary>
[XmlAttribute("First")]
public string First { get; set; }
/// <summary>最后集合</summary>
[XmlAttribute("Last")]
public string Last { get; set; }
/// <summary>错误</summary>
[XmlAttribute("Error")]
public string Error { get; set; } = "0";
/// <summary>文件</summary>
[XmlElement("File")]
public List<File> File { get; set; }
/// <summary>配置</summary>
[XmlElement("Configuration")]
public List<Configuration> Configuration { get; set; }
}
/// <summary>文件</summary>
public class File
{
/// <summary>路径名称</summary>
[XmlAttribute("PathName")]
public string PathName { get; set; }
/// <summary>类型</summary>
[XmlAttribute("Type")]
public string Type { get; set; }
/// <summary>断面号</summary>
[XmlAttribute("TransectNmb")]
public string TransectNmb { get; set; }
/// <summary>名称</summary>
[XmlText]
public string Name { get; set; }
}
/// <summary>配置</summary>
public class Configuration
{
/// <summary>类型</summary>
[XmlAttribute("Type")]
public string Type { get; set; } = "7";
/// <summary>复选</summary>
[XmlAttribute("Checked")]
public string Checked { get; set; } = "1";
/// <summary>状态</summary>
[XmlAttribute("Status")]
public string Status { get; set; } = "0";
/// <summary>错误</summary>
[XmlAttribute("Error")]
public string Error { get; set; } = "0";
/// <summary>命令</summary>
[XmlElement("Commands")]
public Commands Commands { get; set; }
/// <summary>声速仪</summary>
[XmlElement("Depth_Sounder")]
public Depth_Sounder Depth_Sounder { get; set; }
/// <summary>外接罗经</summary>
[XmlElement("Ext_Heading")]
public Ext_Heading Ext_Heading { get; set; }
/// <summary>GPS</summary>
[XmlElement("GPS")]
public GPS GPS { get; set; } = new GPS();
/// <summary>流量</summary>
[XmlElement("Discharge")]
public Discharge Discharge { get; set; }
/// <summary>边坡估算</summary>
[XmlElement("Edge_Estimates")]
public Edge_Estimates Edge_Estimates { get; set; }
/// <summary>偏移量</summary>
[XmlElement("Offsets")]
public Offsets Offsets { get; set; }
/// <summary>处理</summary>
[XmlElement("Processing")]
public Processing Processing { get; set; }
/// <summary>记录</summary>
[XmlElement("Recording")]
public Recording Recording { get; set; }
/// <summary>向导信息</summary>
[XmlElement("Wizard_Info")]
public Wizard_Info Wizard_Info { get; set; }
/// <summary>DM过滤</summary>
[XmlElement("DMFilter")]
public DMFilter DMFilter { get; set; }
}
3.7 其它省略内容的子类
/// <summary>流量汇总</summary>
public class Discharge_Summary { }
/// <summary>命令</summary>
public class Commands { }
/// <summary>声速仪</summary>
public class Depth_Sounder { }
/// <summary>外接罗经</summary>
public class Ext_Heading { }
/// <summary>GPS</summary>
public class GPS { }
/// <summary>流量</summary>
public class Discharge { }
/// <summary>边坡估算</summary>
public class Edge_Estimates { }
/// <summary>偏移量</summary>
public class Offsets { }
/// <summary>处理</summary>
public class Processing { }
/// <summary>记录</summary>
public class Recording { }
/// <summary>向导信息</summary>
public class Wizard_Info { }
/// <summary>DM过滤</summary>
public class DMFilter { }
3.8 测试创建项目文件(包含序列化和反序列化)
public static void CreateFile()
{
WinRiver winRiver = new WinRiver();
Project project = new Project
{
Name = "新文件.MMT",
Version = "2.24.0.8",
Locked = "False",
Flags = "0"
};
Site_Information SiteInformation = new Site_Information
{
Type = "1",
Checked = "1",
Status = "0",
Error = "0",
Agency = "汉口水文分局",
Country = "中国",
County = "武汉市"
};
Site_Discharge SiteDischarge = new Site_Discharge
{
Type = "2",
Checked = "1",
Status = "0",
Error = "0"
};
Transect Transect0 = new Transect
{
Type = "5",
Checked = "1",
Status = "0",
SelectAll = "1",
First = "0",
Last = "0",
Error = "0"
};
File FilePD0 = new File
{
PathName = "D:\\TEST\\新文件\\新文件_000.PD0",
Type = "6",
Name = "新文件_000.PD0",
TransectNmb = "0"
};
File FileASC0 = new File
{
PathName = "D:\\TEST\\新文件\\新文件_000.ASC.TXT",
Type = "14",
Name = "新文件_000.ASC.TXT",
TransectNmb = "0"
};
File FileEH0 = new File
{
PathName = "D:\\TEST\\新文件\\新文件_000.EH.TXT",
Type = "13",
Name = "新文件_000.EH.TXT",
TransectNmb = "0"
};
File FileGPS0 = new File
{
PathName = "D:\\TEST\\新文件\\新文件_000.GPS.TXT",
Type = "11",
Name = "新文件_000.GPS.TXT",
TransectNmb = "0"
};
Transect0.File = new List<File>
{
FilePD0,
FileASC0,
FileEH0,
FileGPS0
};
Configuration configuration = new Configuration
{
Commands = new Commands(),
Depth_Sounder = new Depth_Sounder(),
Ext_Heading = new Ext_Heading(),
Discharge = new Discharge(),
Edge_Estimates = new Edge_Estimates(),
Offsets = new Offsets(),
Processing = new Processing(),
Recording = new Recording(),
Wizard_Info = new Wizard_Info(),
DMFilter = new DMFilter()
};
Transect0.Configuration = new List<Configuration>
{
configuration
};
SiteDischarge.Transect = new List<Transect>
{
Transect0
};
SiteDischarge.Discharge_Summary = new Discharge_Summary();
project.Site_Information = SiteInformation;
project.Site_Discharge = SiteDischarge;
QA_QC qA_QC = new QA_QC();
Collect_Data collect_Data = new Collect_Data();
DisplaySettings displaySettings = new DisplaySettings();
project.QA_QC = qA_QC;
project.Collect_Data = collect_Data;
project.DisplaySettings = displaySettings;
winRiver.Project = project;
Console.WriteLine();
Console.WriteLine("WinRiver对象序列化为XML字符串----------------控制台显示--------------------");
string xml;
XmlSerializer serializer = new XmlSerializer(typeof(WinRiver));//序列化WinRiver对象
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");//命名空间设为空,不显示 xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
using (StringWriter writer = new StringWriter())
{
serializer.Serialize(writer, winRiver, ns);//序列化为 StringWriter 的 xml 字符串
xml = writer.ToString();
Console.WriteLine(xml);//控制台显示
}
Console.WriteLine();
Console.WriteLine("WinRiver对象序列化为XML文件--------------------------------------------");
string ConfigFile = Environment.CurrentDirectory + "\\TestWinRiverMMT.XML";
using (FileStream fileStream = new FileStream(ConfigFile, FileMode.Create))
{
serializer.Serialize(fileStream, winRiver, ns);//序列化为文件流FileStream,保存到文件
}
Console.WriteLine();
Console.WriteLine("XML 字符串反序列化为 WinRiver 对象--------------------------------------");
// 从XML反序列化为对象
WinRiver newWinRiver;
using (StringReader reader = new StringReader(xml))
{
newWinRiver = (WinRiver)serializer.Deserialize(reader);//将 xml 字符串反序列化为WinRiver对象
}
Console.WriteLine(newWinRiver.Project.Name);//控制台显示WinRiver对象的值
Console.WriteLine(newWinRiver.Project.Version);
Console.WriteLine(newWinRiver.Project.Flags);
Console.WriteLine(newWinRiver.Project.Locked);
Console.WriteLine();
Console.WriteLine("XML 文件反序列化为 WinRiver 对象--------------------------------------------");
WinRiver New_WinRiver;
XmlSerializer New_serializer = new XmlSerializer(typeof(WinRiver));// 创建XmlSerializer实例,指定要反序列化的类型
using (FileStream fileStream = new FileStream(ConfigFile, FileMode.Open))
{
New_WinRiver = (WinRiver)New_serializer.Deserialize(fileStream);//将文件流反序列化为 WinRiver 对象
}
Console.WriteLine(New_WinRiver.Project.Name);
Console.WriteLine(New_WinRiver.Project.Version);
Console.WriteLine(New_WinRiver.Project.Flags);
Console.WriteLine(New_WinRiver.Project.Locked);
}
3.9 执行创建文件
private void SaveProjectMenu_Click(object sender, EventArgs e)
{
WinRiverXML.CreateFile();
}
3.10 输出 XML 效果
WinRiver对象序列化为XML字符串----------------控制台显示--------------------
<?xml version="1.0" encoding="utf-16"?>
<WinRiver>
<Project Name="新文件.MMT" Version="2.24.0.8" Flags="0">
<Locked>False</Locked>
<Site_Information Type="1" Checked="1" Status="0" Error="0">
<Agency>汉口水文分局</Agency>
<Country>中国</Country>
<County>武汉市</County>
</Site_Information>
<Site_Discharge Type="2" Checked="1" Status="0" Error="0">
<Transect Type="5" Checked="1" Status="0" SelectAll="1" First="0" Last="0" Error="0">
<File PathName="D:\TEST\新文件\新文件_000.PD0" Type="6" TransectNmb="0">新文件_000.PD0</File>
<File PathName="D:\TEST\新文件\新文件_000.ASC.TXT" Type="14" TransectNmb="0">新文件_000.ASC.TXT</File>
<File PathName="D:\TEST\新文件\新文件_000.EH.TXT" Type="13" TransectNmb="0">新文件_000.EH.TXT</File>
<File PathName="D:\TEST\新文件\新文件_000.GPS.TXT" Type="11" TransectNmb="0">新文件_000.GPS.TXT</File>
<Configuration Type="7" Checked="1" Status="0" Error="0">
<Commands />
<Depth_Sounder />
<Ext_Heading />
<GPS />
<Discharge />
<Edge_Estimates />
<Offsets />
<Processing />
<Recording />
<Wizard_Info />
<DMFilter />
</Configuration>
</Transect>
<Discharge_Summary />
</Site_Discharge>
<QA_QC />
<Collect_Data />
<DisplaySettings />
</Project>
</WinRiver>
WinRiver对象序列化为XML文件--------------------------------------------
XML 字符串反序列化为 WinRiver 对象--------------------------------------
新文件.MMT
2.24.0.8
0
False
XML 文件反序列化为 WinRiver 对象--------------------------------------------
新文件.MMT
2.24.0.8
0
False
四、说明
为了减少篇幅,以上代码省略部分,可以自行类推添加完整。程序在框架 .NET Framework、C# 2017编程环境下,测试正确完成。