前回在C#反射实践的文章中,只介绍了利用反射如何把Xml文件中的数据读取设定到类对象的属性中的方法,这回来介绍如何利用反射机制把值对象写入Xml文件的方法
本文介绍的把值对象写入Xml文件的方法,有以下几点约束
1、值对象中的所有属性必须是string类型的,不含保存子节点信息的属性;
2、自节点数据是保存在范型List中的值对象。
下面的saveToFile()方法是详细的代码实现,
首先需要在类文件中引入以下.Net的命名空间:
代码实现:saveToFile()方法,
注意:在上面的代码要想正常编译,需要声明一下类的字段变量
类的构造器请参照下记代码:
上面的
createXmlRootNode方法,是用来初始化Xml的文档对象-XmlDocument的,实现方式如下:
saveToFile()方法的调用方法如下:
上面代码中的this可以是任意的一个按照本文约束规则编写的值对象,null表示要把这值对象作为Xml文件的根节点进行设置,0这个参数是针对一个值对象中包含有范型List<>类型的字对象的情况,如果没有这种类型,直接设定成0就可以了,如果有请参照saveToFile()方法中第归调用时的设定方法,它的值就是List中对象的索引值。
本文介绍的把值对象写入Xml文件的方法,有以下几点约束
1、值对象中的所有属性必须是string类型的,不含保存子节点信息的属性;
2、自节点数据是保存在范型List中的值对象。
下面的saveToFile()方法是详细的代码实现,
首先需要在类文件中引入以下.Net的命名空间:
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Xml;
- using System.Reflection;
- using System.IO;
- /// <summary>
- /// 把指定的值对象的属性值保存到Xml文件中相应的节点中,并保存到文件中
- /// </summary>
- /// <param name="obj">需要保存的值对象</param>
- /// <param name="parentNode">保存值对象数据的父节点</param>`
- /// <param name="nodeIndex">子节点的索引</param>
- /// <history>
- private void saveToFile(object obj, XmlNode parentNode, int nodeIndex)
- {
- //取得类名称,作为xml文件的节点名。
- string nodeName = obj.GetType().Name;
- //取得指定对象的属性
- PropertyInfo[] proLst = obj.GetType().GetProperties();
- //准备保存值对象属性值得xml的节点对象。
- XmlNode node = null;
- //取得节点的个数
- int nodeCount = xmlDoc.GetElementsByTagName(nodeName).Count;
- //节点存时,取得已经存在的节点
- if (nodeIndex < nodeCount)
- {
- node = xmlDoc.GetElementsByTagName(nodeName).Item(nodeIndex);
- }
- //节点不存在时,创建一个新的节点,并把这个节点追加到xml的文档对象中
- if (node == null)
- {
- node = xmlDoc.CreateElement(nodeName);
- if (parentNode == null)
- {
- this.rootNode.AppendChild(node);
- }
- else
- {
- parentNode.AppendChild(node);
- }
- }
- //把对象的属性值保存到Xml文档对象的对应的节点属性中
- foreach (PropertyInfo pro in proLst)
- {
- XmlElement xmlE = (XmlElement)node;
- //属性是值对象的场合,只认string数据类型哦
- if (pro.PropertyType.Name.IndexOf("String") >= 0)
- {
- //设定xml节点的属性值
- xmlE.SetAttribute(pro.Name, pro.GetValue(obj, null).ToString());
- }
- //属性是范型的场合,此默认数据类型是范型List<>
- else if (pro.PropertyType.IsGenericType == true)
- {
- //利用反射取得属性的get方法。
- MethodInfo m = pro.GetGetMethod();
- //利用反射调用属性的get方法,取得属性的值
- object rs = m.Invoke(obj, null);
- //取得List中的对象数
- int count = (int)rs.GetType().GetProperty("Count").GetValue(rs, null);
- for (int i = 0; i < count; i++)
- {
- //取得List中指定索引的对象
- object param = rs.GetType().GetProperty("Item").GetValue(rs, new object[] { i });
- //第归调用实现子节点的向Xml的文档对象的保存
- saveToFile(param, node, i);
- }
- }
- //Xml节点对象的场合
- else
- {
- //利用反射取得属性的get方法。
- MethodInfo m = pro.GetGetMethod();
- //利用反射调用属性的get方法,取得属性的值
- object rs = m.Invoke(obj, null);
- saveToFile(rs, node, 0);
- }
- }
- //把xml的文档对象保存到指定的xml文件中
- xmlDoc.Save(this.filePath);
- }
- //xml文件的路径
- private string filePath;
- //保存xml文件信息的文档对象
- private XmlDocument xmlDoc = null;
- //xml文件的根节点名
- private string rootNodeName = "ReflectionTest";
- //xml文件的根节点对象
- private XmlNode rootNode;
- //构造器
- public TestConfig(string configFilePath)
- {
- xmlDoc = new XmlDocument();
- createXmlRootNode(filePath);
- filePath = configFilePath;
- }
- /// <summary>
- /// 初始化XMLDocument对象
- /// </summary>
- /// <param name="fileName">Xml的文件名</param>
- private void createXmlRootNode(string fileName)
- {
- if (File.Exists(fileName) == true)
- {
- xmlDoc.Load(fileName);
- rootNode = xmlDoc.GetElementsByTagName(rootNodeName).Item(0);
- }
- else
- {
- xmlDoc.AppendChild(xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", null));
- rootNode = xmlDoc.CreateElement(rootNodeName);
- xmlDoc.AppendChild(rootNode);
- }
- }
- /// <summary>
- /// 把指定的值对象的属性值保存到Xml文件中
- /// </summary>
- public void saveToXml()
- {
- saveToFile(this, null, 0);
- }