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

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="" OrderID="" IsMustExecute="true">
<Settings>
<Setting Key="ClassDays_30d" Value="" />
</Settings>
</Rule>
<Rule Code="" OrderID="" IsMustExecute="true">
<Settings>
<Setting Key="GameRole" Value="true" />
</Settings>
</Rule>
</Rules>
</Gateway>
<!--PayPalCreditCard-->
<Gateway Code="BBB">
<Rules>
<Rule Code="" OrderID="" IsMustExecute="true">
</Rule>
<Rule Code="" OrderID="" IsMustExecute="true">
<Settings>
<Setting Key="SumOrderAmount_7d" Value="" />
</Settings>
</Rule>
<Rule Code="" OrderID="" IsMustExecute="true">
<Settings>
<Setting Key="High1" Value="-60" />
<Setting Key="High2" Value="-30" />
<Setting Key="High3" Value="-10" />
</Settings>
</Rule>
</Rules>
</Gateway>
</RuleSettings>

我们来看这个文件,它的整体结构如下:根节点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; }
}

其中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="",
IsMustExecute=true,
OrderID="",
Settings=new Settings
{
Setting=new List<Setting>()
{
new Setting{key="ClassDays_30d",value=""},
new Setting{key="GameRole",value="true"}
},
},
},
new Rule()
{
Code="",
IsMustExecute=true,
OrderID="",
Settings=new Settings
{
Setting=new List<Setting>()
{
new Setting{key="GameRole",value="true"}
},
},
},
},
},
new Gateway()
{
Code="BBB",
Rules=new List<Rule>()
{
new Rule()
{
Code="",
IsMustExecute=true,
OrderID="",
Settings=null
},
new Rule()
{
Code="",
IsMustExecute=true,
OrderID="",
Settings=new Settings
{
Setting=new List<Setting>()
{
new Setting{key="SumOrderAmount_7d",value=""}
},
},
},
new Rule()
{
Code="",
IsMustExecute=true,
OrderID="",
Settings=new Settings
{
Setting=new List<Setting>()
{
new Setting{key="High1",value=""},
new Setting{key="High2",value=""},
new Setting{key="High3",value=""}
},
},
},
},
}
},
}; XmlHelper.Save(rs, Server.MapPath("Xml//RuleSetting.xml"));

生成的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="" OrderID="" IsMustExecute="true">
<Settings>
<Setting>
<Setting key="ClassDays_30d" value="" />
<Setting key="GameRole" value="true" />
</Setting>
</Settings>
</Rule>
<Rule Code="" OrderID="" IsMustExecute="true">
<Settings>
<Setting>
<Setting key="GameRole" value="true" />
</Setting>
</Settings>
</Rule>
</Rules>
</Gateway>
<Gateway Code="BBB">
<Rules>
<Rule Code="" OrderID="" IsMustExecute="true" />
<Rule Code="" OrderID="" IsMustExecute="true">
<Settings>
<Setting>
<Setting key="SumOrderAmount_7d" value="" />
</Setting>
</Settings>
</Rule>
<Rule Code="" OrderID="" IsMustExecute="true">
<Settings>
<Setting>
<Setting key="High1" value="" />
<Setting key="High2" value="" />
<Setting key="High3" value="" />
</Setting>
</Settings>
</Rule>
</Rules>
</Gateway>
</Gateway>
</RuleSettings>

对于根节点 RuleSettings可以加上

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

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

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

2013-10-14 晚

关于XML与类型Class的映射的更多相关文章

  1. Taurus.MVC WebAPI 入门开发教程3:路由类型和路由映射。

    系列目录 1.Taurus.MVC WebAPI  入门开发教程1:框架下载环境配置与运行. 2.Taurus.MVC WebAPI 入门开发教程2:添加控制器输出Hello World. 3.Tau ...

  2. hibernate Java 时间和日期类型的 Hibernate 映射

    基础知识: 在 Java 中, 代表时间和日期的类型包含: java.util.Date 和 java.util.Calendar. 此外, 在 JDBC API 中还提供了 3 个扩展了 java. ...

  3. Java 时间和日期类型的 Hibernate 映射

    以下情况下必须显式指定 Hibernate 映射类型 一个 Java 类型可能对应多个 Hibernate 映射类型. 例如: 如果持久化类的属性为 java.util.Date 类型, 对应的 Hi ...

  4. 三 MyBatis配置文件SqlMapCofing.xml(属性加载&类型别名配置&映射文件加载)

    SqlMapCofing:dtd,属性加载有固定的顺序Content Model properties:加载属性文件 typeAliases:别名配置 1 定义单个别名:不区分大小写 核心配置: 映射 ...

  5. MyBatis里字段到枚举类型的转换/映射

    一.简介 我们在用MyBatis里,很多时间有这样一个需求:bean里有个属性是枚举,在DB存储时我们想存的枚举的代号,从DB拿出来时想直接映射成目标枚举类型,也即代号字段与Java枚举类的相互类型转 ...

  6. MyBatis之基于XML的属性与列名映射

    上一博客主要是对单表的增删改查,比较简单,而且每个属性与table表的列都是一一对应名字也一样,今天主要学习属性与table表列名不一致的处理,主要有两种一是属性与列名不一致,二是枚举的情况,这里暂时 ...

  7. Dapper逆天入门~强类型,动态类型,多映射,多返回值,增删改查+存储过程+事物案例演示

    Dapper的牛逼就不扯蛋了,答应群友做个入门Demo的,现有园友需要,那么公开分享一下: 完整Demo:http://pan.baidu.com/s/1i3TcEzj 注 意 事 项:http:// ...

  8. SqlMapConfig.xml配置文件中的mapper映射器标签

    Mapper配置的几种方式: 1. <mapper resource=" "/> 使用相对于类路径的资源 如:<mapper resource="com ...

  9. 对于Oracle中Number类型的字段映射成Java中的具体类型的问题

    我在Oracle中给一个用户Id字段设置为Number类型,使用JDBC在完成ORM的时候,以为其可以自动转换为Integer,因为我的POJO类id使用的就是Integer.但事实是,我在测试的时候 ...

随机推荐

  1. ELK beats通用配置说明(12th)

    Beats配置文件是以YAML语法,该文件包含用于所有的beats的通用配置选项,以及其特点的选项.下面说说通用的配置,特定的配置要看各自beat文档. 通用的配置如下几部分: Shipper Out ...

  2. OpenCV入门学习笔记

    OpenCV入门学习笔记 参照OpenCV中文论坛相关文档(http://www.opencv.org.cn/) 一.简介 OpenCV(Open Source Computer Vision),开源 ...

  3. 针对 .NET 框架的安全编码指南

      此主题尚未评级 - 评价此主题 发布日期 : 10/9/2004 | 更新日期 : 10/9/2004 Microsoft Corporation 适用于: Microsoft .NET 框架 摘 ...

  4. ECSHOP在线手册布局参考图--积分商城 exchange_list.dwt

        A.购物车 1,设置方法 程序自动读取购物车的商品数量 2,代码相关 cart.lbi 中 {insert_scripts files='transport.js'} <div clas ...

  5. css3动画属性中的transition属性

    一.语法 transition: property duration timing-function delay; 值 描述 transition-property 规定设置过渡效果的 CSS 属性的 ...

  6. hdu 2844 Coins (多重背包)

    题意是给你几个数,再给你这几个数的可以用的个数,然后随机找几个数来累加, 让我算可以累加得到的数的种数! 解题思路:先将背包初始化为-1,再用多重背包计算,最后检索,若bb[i]==i,则说明i这个数 ...

  7. ECshop彻底去版权(同时适用于2.7.3)

    前台部分: 1:去掉头部TITLE部分的ECSHOP演示站 Powered by ecshop前者”ECSHOP演示站”在后台商店设置 – 商店标题修改后者” Powered by ecshop”打开 ...

  8. 教你50招提升ASP.NET性能(九):显式的使用using语句减少内存泄露

    (15)Reduce memory leaks dramatically with the “using” statement 招数15: 显式的使用using语句减少内存泄露 If a type i ...

  9. 放弃移动版Flash而非AIR

    之前看到标题为"Adobe放弃移动版flash"的新闻,我很震惊,为何Adobe会放弃这么一个大市场呢? 这样无疑打击原来在flash的开发上的应用,我想很多人和我想的一样,fla ...

  10. AD新建用户、组、OU

    #新建用户 import-csv d:\AD\Users.csv | Foreach {New-ADUser -Name $_.Name -Path $_.Path -samAccountName $ ...