我们知道数据的持久化是编程必须面对的问题。我们可以保存数据到数据库、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. 射频识别技术漫谈(8)——动物标签【worldsing笔记】

    动物标签也是工作在TTF模式的ID(Identification)卡.之所以通常称为动物标签,估计是因为一来和识别人的ID卡相区分,二是因为动物不如人听话,人的ID卡可以做成卡片形状拿在手上,而动物不 ...

  2. IOS知识小记

    iOS开发 小知识点 http://www.cnblogs.com/tangbinblog/archive/2012/07/20/2601324.html Objective-C中的instancet ...

  3. Unity3d 使用NPOI读写Excel 遇到的问题

    开发环境:unity5.3  NPOI(.net 2.0版  http://npoi.codeplex.com/) 运行环境:PC版, 其他平台没有测试 先上效果图: 实现步骤: 1.新建一个Exce ...

  4. 如何避免regionServer宕机

    为什么regionserver 和Zookeeper的session expired? 可能的原因有 1. 网络不好. 2. Java full GC, 这会block所有的线程.如果时间比较长,也会 ...

  5. 使用纯代码定义UICollectionView和自定义UICollectionViewCell

    1.自定义UICollectionView 2.实现<UICollectionViewDataSource,UICollectionViewDelegateFlowLayout,UICollec ...

  6. HDU 1718 Rank counting sort解法

    本题是利用counting sort的思想去解题. 注意本题,好像利用直接排序,然后查找rank是会直接被判WA的.奇怪的推断系统. 由于分数值的范围是0到100,很小,而student 号码又很大, ...

  7. C#-禁止调整窗体的大小

    要是想禁止调整窗体的大小,可以查看:FormBorderStyle属性,该属性的设置中有一个"FixedSingle"的选择项,它可以禁止调整窗体的大小.

  8. BZOJ 1028: [JSOI2007]麻将 暴力

    1028: [JSOI2007]麻将 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/prob ...

  9. android学习日记24--Android 菜单开发

    菜单是任何应用程序必不可少的一项.按下Menu键或者长按某个View就会弹出相应菜单,当然前提是应用程序有实现菜单功能. Android平台下的菜单有:Options Menu(选项菜单).Subme ...

  10. flash builder 4.7 debug via usb device iPhone 4s - device not found

    http://forums.adobe.com/message/4865192 Please provide more info on the above issue: 1.What is the m ...