我们知道数据的持久化是编程必须面对的问题。我们可以保存数据到数据库、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. java properties 文件中书写相对路径

    工程src下的properties 文件要引用发布到D:\work\apache-tomcat-7.0.52\webapps\项目名称\certs这个地址下的文件,properties 中的文件路径应 ...

  2. MAC 终端 显示隐藏文件 关闭显示隐藏文件

    1.显示隐藏文件夹显示:defaults write com.apple.finder AppleShowAllFiles -bool true (1)复制“defaults write com.ap ...

  3. java中几个特殊的类

    1 内部类-----是在其他类中的类 1.1 内部类的定义 将类定义为 class xxxx{... ...}置于某个类的内部即可‘ 内部类编译时生成 xxxx$xxxx的class文件 内部类不能够 ...

  4. Qt 经典出错信息之”Basic XLib functionality test failed!”(Z..z..)

    此完整出错信息是在./configure阶段 Basic XLib functionality test failed! You might need to modify the include an ...

  5. 安装Intel HAXM为Android 模拟器加速,30秒内启动完成

    要求 必备知识 windows 7 基本操作. 运行环境 windows 7(64位); Android Studio 1.1.0;JDK 1.7.0_75(64位);android-sdk_r24 ...

  6. 将Excel数据导入MySql

    1.将选中的数据快儿拷贝到一个TXT文本文件中(记得把后面的空格消掉..),假如存到“D:\data.txt”这个位置里. 2.根据要导入的数据快儿建立MySql数据库和表,然后进入命令提示符里使用命 ...

  7. discuz!版本号信息改动步骤

    建完网站后,就到了改动discuz! 论坛的步骤了,,将其改动为自己喜欢的样子.是非常有意思的,废话不多说了.以下给大家介绍改动的方法. 1.[改动后台-首页的版权]打开ftp.连接网站,进入到:/f ...

  8. 从零开始学android开发-项目debug

    在红框处能看到变量值

  9. js 类似php中foreach的方法

    参考下面实例 <script>var arr =  {    'a' : '111111',    'b' : '222222',    'c' : '333333'};for(var k ...

  10. BZOJ 2298: [HAOI2011]problem a 动态规划

    2298: [HAOI2011]problem a Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnli ...