• 关于XML与类型Class的映射


    我们知道数据的持久化是编程必须面对的问题。我们可以保存数据到数据库、Excel表、XML文件、TXT文件等等。那么我们编程中经常会遇到对Xml文件的操作。在http://www.cnblogs.com/fengchengjushi/p/3266191.html这里我已经简单总结了传统的Xml文件操作办法。也引出了对Xml文件和类型Class之间可以进行映射,从而简化操作,提高效率。那么,很多时候我们并不一定能自己定义好相应的映射Class。比方说,对业已存在的Xml文件的操作。那么,我们就需要看Xml文件的节点构成,然后反向由Xml文件映射出需要的Class。接下来,我就以demo为例。

    XmlHelper帮助类

     public class XmlHelper
        {
            #region XML序列化
            /// <summary>
            /// 文件化XML序列化
            /// </summary>
            /// <param name="obj">对象</param>
            /// <param name="filename">文件路径</param>
            public static void Save(object obj, string filename)
            {
                FileStream fs = null;
                try
                {
                    fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
                    XmlSerializer serializer = new XmlSerializer(obj.GetType());
                    serializer.Serialize(fs, obj);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    if (fs != null) fs.Close();
                }
            }
    
            /// <summary>
            /// 文件化XML反序列化
            /// </summary>
            /// <param name="type">对象类型</param>
            /// <param name="filename">文件路径</param>
            public static object Load(Type type, string filename)
            {
                FileStream fs = null;
                try
                {
                    fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    XmlSerializer serializer = new XmlSerializer(type);
                    return serializer.Deserialize(fs);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    if (fs != null) fs.Close();
                }
            }
            #endregion
        }
    View Code

    Test.xml文件

    <?xml version="1.0" encoding="utf-8" ?>
    <RuleSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <Gateway Code="AAA">
        <Rules>
          <Rule Code="202" OrderID="1" IsMustExecute="true">
            <Settings>
              <Setting Key="ClassDays_30d" Value="1000" />
            </Settings>
          </Rule>
          <Rule Code="301" OrderID="2" IsMustExecute="true">
            <Settings>
              <Setting Key="GameRole" Value="true" />
            </Settings>
          </Rule>
        </Rules>
      </Gateway>
      <!--PayPalCreditCard-->
      <Gateway Code="BBB">
        <Rules>
          <Rule Code="100" OrderID="1" IsMustExecute="true">
          </Rule>
          <Rule Code="201" OrderID="2" IsMustExecute="true">
            <Settings>
              <Setting Key="SumOrderAmount_7d" Value="500" />
            </Settings>
          </Rule>
          <Rule Code="800" OrderID="23" IsMustExecute="true">
            <Settings>
              <Setting Key="High1" Value="-60" />
              <Setting Key="High2" Value="-30" />
              <Setting Key="High3" Value="-10" />
            </Settings>
          </Rule>
        </Rules>
      </Gateway>
    </RuleSettings>
    View Code

    我们来看这个文件,它的整体结构如下:根节点RuleSettings,它包含Gateway节点的集合。Gateway节点又包含Rules(单个)节点,Rules节点又包含Rule节点集合,Rule节点下面包含单个Settings(为了讲讲它的特别之处,下面我们对它采取异于Rules节点的处理方法)节点,这之下包含多个Setting节点。而且,Settings节点可以没有。

    现在开始映射对应的Class类型。一个节点实际上是一个XmlElement 也对应一个Class,属性即XmlAttribute就对Class的属性,如果该节点有InnerText就在定义的属性上加XmlText。那么我们对应出如下类型

      public class RuleSettings
        {
            public List<Gateway> Gateway { get; set; }
        }
    
        public class Gateway
        {
            [XmlAttribute("Code")]
            public string Code { get; set; }
            public List<Rule> Rules { get; set; }
        }
        public class Rule
        {
            [XmlAttribute("Code")]
            public string Code { get; set; }
            [XmlAttribute("OrderID")]
            public string OrderID { get; set; }
            [XmlAttribute("IsMustExecute")]
            public bool IsMustExecute { get; set; }
            //[XmlAttribute("Settings")]
            [XmlElement("Settings")]
            public Settings Settings { get; set; }
            
        }
        /// <summary>
        /// 注:对于这种无XmlAttribute的节点。且它包含子节点。我们这样做时
        /// 必须给Settinghe上面的Settings标明是XmlElment
        /// 不然会多出一个Setting节点
        /// 或者直接在上面使用public List<Setting> Settings { get; set; }
        /// 省去Settings类
        /// </summary>
        public class Settings
        {
            [XmlElement("Setting")]
            public List<Setting> Setting { get; set; }
        }
        public class Setting
        {
            [XmlAttribute("key")]
            public string key { get; set; }
            [XmlAttribute("value")]
            public string value { get; set; }
        }
    View Code

    其中Rules和Settings节点就是无任何属性,且包含子节点集合的节点。对于Rules我们不考虑映射一个Class,采取在Gateway节点下面直接定义Rule集合Rules。同时设置它的节点名称为Settings。对于Settings我们同样定义一个类型。它里面有一个属性是Setting节点的集合。此时。我们必须在Rule类型下的Settings加上XmlElement属性。

    接下来就是反序列化了

     RuleSettings rs = new RuleSettings
                {
                    Gateway = new List<Gateway>()
                    {
                       new Gateway()
                       {
                           Code="AAA",
                           Rules=new List<Rule>()
                           {
                               new Rule()
                               {
                                   Code="201",
                                   IsMustExecute=true,
                                   OrderID="1",
                                   Settings=new Settings
                                   {
                                       Setting=new List<Setting>()
                                       {
                                            new Setting{key="ClassDays_30d",value="12"},
                                            new Setting{key="GameRole",value="true"}
                                       },
                                   },
                               },
                               new Rule()
                               {
                                   Code="301",
                                   IsMustExecute=true,
                                   OrderID="2",
                                   Settings=new Settings
                                   {
                                       Setting=new List<Setting>()
                                       {
                                            new Setting{key="GameRole",value="true"}
                                       },
                                   },
                               },
                           },
                       },
                       new Gateway()
                       {
                           Code="BBB",
                           Rules=new List<Rule>()
                           {
                               new Rule()
                               {
                                   Code="100",
                                   IsMustExecute=true,
                                   OrderID="1",
                                   Settings=null
                               },
                               new Rule()
                               {
                                   Code="201",
                                   IsMustExecute=true,
                                   OrderID="2",
                                   Settings=new Settings
                                   {
                                       Setting=new List<Setting>()
                                       {
                                            new Setting{key="SumOrderAmount_7d",value="600"}
                                       },
                                   },
                               },
                               new Rule()
                               {
                                   Code="800",
                                   IsMustExecute=true,
                                   OrderID="23",
                                   Settings=new Settings
                                   {
                                       Setting=new List<Setting>()
                                       {
                                            new Setting{key="High1",value="60"},
                                            new Setting{key="High2",value="10"},
                                            new Setting{key="High3",value="10"}
                                       },
                                   },
                               },
                           },
                       }
                    },
                };
    
                XmlHelper.Save(rs, Server.MapPath("Xml//RuleSetting.xml"));
    View Code

    生成的RuleSetting.xml文件如下

    <?xml version="1.0"?>
    <RuleSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <Gateway>
        <Gateway Code="AAA">
          <Rules>
            <Rule Code="201" OrderID="1" IsMustExecute="true">
              <Settings>
                <Setting>
                  <Setting key="ClassDays_30d" value="12" />
                  <Setting key="GameRole" value="true" />
                </Setting>
              </Settings>
            </Rule>
            <Rule Code="301" OrderID="2" IsMustExecute="true">
              <Settings>
                <Setting>
                  <Setting key="GameRole" value="true" />
                </Setting>
              </Settings>
            </Rule>
          </Rules>
        </Gateway>
        <Gateway Code="BBB">
          <Rules>
            <Rule Code="100" OrderID="1" IsMustExecute="true" />
            <Rule Code="201" OrderID="2" IsMustExecute="true">
              <Settings>
                <Setting>
                  <Setting key="SumOrderAmount_7d" value="600" />
                </Setting>
              </Settings>
            </Rule>
            <Rule Code="800" OrderID="23" IsMustExecute="true">
              <Settings>
                <Setting>
                  <Setting key="High1" value="60" />
                  <Setting key="High2" value="10" />
                  <Setting key="High3" value="10" />
                </Setting>
              </Settings>
            </Rule>
          </Rules>
        </Gateway>
      </Gateway>
    </RuleSettings>
    View Code

    对于根节点 RuleSettings可以加上

    [XmlRoot(Namespace = "http://msdn.microsoft.com/vsdata/xsd/vsdh.xsd")]

    其实上面处理一个节点下有多个字节点的集合时我们可以采用数组。当然个人习惯。可以自己试试,效果是一样的。

    就写到这儿,此处受http://www.cnblogs.com/fish-li/的文章影响,它介绍很细致,你们可以看下。总感觉看了,就想自己写,理解得更透彻点。

    2013-10-14 晚

  • 相关阅读:
    「干货分享」我所在团队的竞品分析模板--附下载
    框架用多了真的会死人的,spring-cloud全家桶与mybitais 集成完整示例(附下载)
    聊聊区块链,虽然我不挖矿!
    从厕所排队引发的产品设计方案思考
    基于spring-boot和docker-java实现对docker容器的动态管理和监控[附完整源码下载]
    Spring-boot原理(附带实现一个spring-boot-starter实例和代码下载)
    Zookeeper+websocket实现对分布式服务器的实时监控(附源码下载)
    「干货分享」模块化编程和maven配置实践一则
    【干货分享】大话团队的GIT分支策略进化史
    项目协作管理平台-teambition和tapd--深度体验
  • 原文地址:https://www.cnblogs.com/fengchengjushi/p/3369386.html
Copyright © 2020-2023  润新知