关于XML与类型Class的映射
分类:
IT文章
•
2024-05-29 19:00:25
我们知道数据的持久化是编程必须面对的问题。我们可以保存数据到数据库、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"));