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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值