我们知道数据的持久化是编程必须面对的问题。我们可以保存数据到数据库、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. support-v4不能查看源码

    在Android实际开发过程中往往会遇到使用v4,v7或v13兼容包中的一些类如ViewPager,Fargment等,但却无法关联源码 具体步骤: 1 右击Android项目中libs文件夹下的an ...

  2. C++ vector的用法

    其实我是一个比较懒惰的人 我最喜欢的循环方式是for(int i=0;i<length;i++) 同样也可以 for (unsigned i=0; i<sz; i++) myvector[ ...

  3. VB二进制文件读写

    数组存取 存数组 Private Sub Command2_Click() Dim fileNumber As Integer Dim S9 As String Dim k As Integer Di ...

  4. 1.(1)编写一个接口ShapePara,要求: 接口中的方法: double getArea():获得图形的面积。double getCircumference():获得图形的周长 (2)编写一个圆类Circle,要求:圆类Circle实现接口ShapePara。 该类包含有成员变量: radius:public 修饰的double类型radius,表示圆的半径。 x:private修饰的dou

    package jiekou1; public interface ShapePara { //定义常量PI final double PI=3.14; //定义抽象方法 //获得图形面积 doubl ...

  5. Codeforces Round #324 (Div. 2) A. Olesya and Rodion 水题

    A. Olesya and Rodion Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/584/p ...

  6. Java正則表達式入门

     众所周知,在程序开发中,难免会遇到须要匹配.查找.替换.推断字符串的情况发生,而这些情况有时又比較复杂,假设用纯编码方式解决,往往会浪费程序猿的时间及精力.因此,学习及使用正則表達式,便成了解决这一 ...

  7. 使MySQL 支持繁体字

    要 MySQL 支持繁体字,可以将相关编码设置为 UTF8 (也叫 UTF-8).编码的设置从浏览器到表字段,一个都不能少: 浏览器设置 HTML设置 服务器 Request 对象设置 数据库连接设置 ...

  8. 彻底解决android读取中文txt的乱码(自动判断文档类型并转码

    原文:http://blog.csdn.net/handsomedylan/article/details/6138400 public String convertCodeAndGetText(St ...

  9. open_table与opened_table --2

    好多人在调优Mysql的时候,总是对open_tables和opend_tables两个参数分别不清. 网上好多解释都是这样的:open_tables:当前打开表的数量opened_tables:当前 ...

  10. Windows 7 Ultimate(旗舰版)SP1 32/64位官方原版下载(2011年5月12日更新版)

    MSDN于2011年5月12日,最新发布简体中文Windows 7 Ultimate 旗舰版 SP1 DVD镜像安装包,分32位和64位两个版本.最新发行代号分别是:677486(32位),67740 ...