coco

随心。。。随性。。。随行。。。

  博客园  ::  ::  ::  ::  :: 管理

我们知道数据的持久化是编程必须面对的问题。我们可以保存数据到数据库、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 晚

posted on 2013-10-14 23:14  深谷&幽兰  阅读(2930)  评论(0编辑  收藏  举报