XML数据文件灵活而强大,在C#中,操作起来也十分方便.我们常用XML文件保存少量的数据,如系统配置信息,用户个性数据...,而对这些数据的操作最常用的就是读取,写入和删除相关的结点.本人的实际的应用过程中,逐步形成了以下XML配置文件的操作类.下面的这个类为大家提供了一系列更加简捷的操作方法,无需再考虑文件或结点是否存在.
代码
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.XPath;
namespace LuckerSoft
{
/// <summary>
/// 该XML文件操作类提供一系统自动完成的操作类.包括常用的数据读取,写入与删除.
/// 支持非字符型数据(即所有支持序列化的object类型)的操作.
/// 并具有文件或结点不存在时自动创建的功能.
/// 该类采用静态类设计,用类名直接调用其公有方法,主要适用于对XML文件中单个结点的操作
/// 作者:Lucker
/// 日期:2009年12月29日
/// 版本:1.0.0
/// </summary>
public static class MyXML
{
/// <summary>
/// 从指定的XML文件中读取指定路径下所有结点的值
/// </summary>
/// <param name="XMLFile">带路径的XML文件名</param>
/// <param name="Path">带路径的结点名</param>
/// <returns></returns>
public static string[] ReadNodes(string XMLFile, string Path)
{
string Values="";
XmlDocument xmldoc = CheckFileExit(XMLFile);
XmlNode Node = FindNode(xmldoc, Path);
foreach (XmlNode node in Node.ChildNodes)
{
Values += node.Name.ToString() + ",";
}
return Values.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
}
/// <summary>
/// 从指定的XML文件中读取指定路径下单个结点的值.当结点不存在时,根据所提供默认值自动创建.
/// </summary>
/// <param name="XMLFile"></param>
/// <param name="Path"></param>
/// <param name="DefaultValue">结点不存在时,提供的默认值</param>
/// <returns></returns>
public static string ReadNode(string XMLFile, string Path, string DefaultValue)
{
XmlDocument xmldoc = CheckFileExit(XMLFile);
XmlNode Node = FindNode(xmldoc, Path);
if (Node != null)
{
return Node.InnerText;
}
else
{
WriteNode(XMLFile, Path, DefaultValue);
return DefaultValue;
}
}
/// <summary>
/// 读取一个object类型的结点数据.
/// </summary>
/// <param name="XMLFile"></param>
/// <param name="Path"></param>
/// <param name="DefaultValue">object类型的数据实际上是经过序列化后转换成string保存在文件中的</param>
/// <returns></returns>
public static object ReadNode(string XMLFile, string Path, object DefaultValue)
{
//读出文件中的string值
string Value=ReadNode(XMLFile, Path, Object2String(DefaultValue));
//再将读取出来的string数据需要转化成object对象.
object o= String2Object(Value);
return o;
}
/// <summary>
/// 向指定的XML文件中写入指定路径的结点数据.当指定结点不存在是时,将沿路径依次创建各父结点
/// </summary>
/// <param name="XMLFile"></param>
/// <param name="Path"></param>
/// <param name="Value">结点值</param>
public static void WriteNode(string XMLFile, string Path, string Value)
{
XmlDocument myDoc = CheckFileExit(XMLFile);
PathNode = null;
PathDepth = 0;
ParentNode = null;
CheckPath(myDoc, Path);
XmlNode Node = FindNode(myDoc, Path);
if (Node != null)
{
UpdateXmlNode(Value, Node);
}
myDoc.Save(XMLFile);
}
/// <summary>
/// 写入一个object类型的对象.
/// </summary>
/// <param name="XMLFile"></param>
/// <param name="Path"></param>
/// <param name="Value"></param>
public static void WriteNode(string XMLFile, string Path, object Value)
{
//经序列化后转换成string型后再写入.
WriteNode(XMLFile, Path, Object2String(Value));
}
/// <summary>
/// 删除指定的结点
/// </summary>
/// <param name="XMLFile"></param>
/// <param name="Path"></param>
/// <returns></returns>
public static bool DeleteNode(string XMLFile, string Path)
{
XmlDocument myDoc = CheckFileExit(XMLFile);
XmlNode Node = FindNode(myDoc, Path);
if(Node!=null)
{
if (Node.ParentNode != null)
{
Node.ParentNode.RemoveChild(Node);
}
else
{
myDoc.RemoveChild(Node);
}
myDoc.Save(XMLFile);
}
return true;
}
#region 私有方法
/// <summary>
/// 更新指定结点的值
/// </summary>
/// <param name="TextName">结点的值</param>
/// <param name="XNe">要更新的结点</param>
/// <returns></returns>
private static bool UpdateXmlNode(string TextName, XmlNode XNe)
{
if (XNe != null)
{
XNe.InnerText = TextName;
return true;
}
else
return false;
}
/// <summary>
/// 插入一个指定的XML元素
/// </summary>
/// <param name="myDoc"></param>
/// <param name="ElementName">元素名</param>
/// <param name="Text">元素值</param>
/// <returns></returns>
private static XmlNode InsertXmlElement(XmlDocument myDoc, string ElementName, string Text)
{
if (ElementName != "")
{
XmlElement XEt = myDoc.CreateElement("",ElementName,"");
XEt.InnerText = Text;
return (XmlNode)XEt;
}
else
{
return null;
}
}
static string[] PathNode = null;
static int PathDepth=0;
static XmlNode ParentNode;
/// <summary>
/// 获取路径结点集指定深度的路径表示
/// </summary>
/// <param name="depth"></param>
/// <returns></returns>
private static string GetPath(int depth)
{
string path = "";
for (int i = 0; i < depth && i < PathNode.Length; i++)
{
path += PathNode[i] + "/";
}
return path.Substring(0,path.Length - 1);
}
/// <summary>
/// 递归检查指定路径上的结点是否存在,不存在则创建
/// </summary>
/// <param name="myDoc"></param>
/// <param name="Path"></param>
private static void CheckPath(XmlDocument myDoc, string Path)
{
if (PathNode == null)
{
PathNode = Path.Split(new char[] { '/' });
PathDepth = 0;
}
if (PathDepth < PathNode.Length)
{
string NewPath = GetPath(++PathDepth);
string Name = PathNode[PathDepth-1];
XmlNode Node = FindNode(myDoc, NewPath);
if (Node == null)
{
XmlNode NewNode = InsertXmlElement(myDoc, Name, null);
ParentNode.AppendChild(NewNode);
ParentNode = FindNode(myDoc, NewPath);
}
else
{
ParentNode = Node;
}
CheckPath(myDoc, NewPath);
}
}
/// <summary>
/// 查询指定路径上的第一个结点
/// </summary>
/// <param name="myDoc"></param>
/// <param name="Path"></param>
/// <returns></returns>
private static XmlNode FindNode(XmlDocument myDoc, string Path)
{
//Path:aaaa/bbbb/cccc
XmlNode myNode = myDoc.SelectSingleNode(Path);
if (!(myNode == null))
{
return myNode;
}
return null;
}
/// <summary>
/// 查询指定路径上的所有结点
/// </summary>
/// <param name="myDoc"></param>
/// <param name="Path"></param>
/// <returns></returns>
private static XmlNodeList FindNodes(XmlDocument myDoc, string Path)
{
//Path:aaaa/bbbb/cccc
XmlNodeList myNodeList = myDoc.SelectNodes(Path);
if (!(myNodeList == null))
{
return myNodeList;
}
return null;
}
/// <summary>
/// 查询指定的XML文件是否存在.如果不存在,则创建一个具有默认根结点的XML文件.
/// </summary>
/// <param name="XMLFile"></param>
/// <returns></returns>
private static XmlDocument CheckFileExit(string XMLFile)
{
XmlDocument xmldoc = new XmlDocument();
if (File.Exists(XMLFile))
{
try
{
xmldoc.Load(XMLFile);
}
catch (Exception ex)
{
throw new Exception("载入XML文件[" + XMLFile + "]失败.\r\n"+ex.Message);
}
}
else
{
XmlDeclaration xn = xmldoc.CreateXmlDeclaration("1.0", "gb2312", null);
xmldoc.AppendChild(xn);
XmlElement xmlelem = xmldoc.CreateElement("", "打印项目模板", "");
xmldoc.AppendChild(xmlelem);
xmldoc.Save(XMLFile);
}
return xmldoc;
}
/// <summary>
/// 序列化为二进制字节数组
/// </summary>
/// <param name="request">要序列化的对象</param>
/// <returns>字节数组</returns>
private static byte[] SerializeBinary(object request)
{
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter serializer = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
System.IO.MemoryStream memStream = new System.IO.MemoryStream();
serializer.Serialize(memStream, request);
return memStream.GetBuffer();
}
/// <summary>
/// 从二进制数组反序列化得到对象
/// </summary>
/// <param name="buf">字节数组</param>
/// <returns>得到的对象</returns>
private static object DeserializeBinary(byte[] buf)
{
System.IO.MemoryStream memStream = new MemoryStream(buf);
memStream.Position = 0;
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter deserializer =
new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
object newobj = deserializer.Deserialize(memStream);
memStream.Close();
return newobj;
}
private static string Object2String(object Obj)
{
StringBuilder sb = new StringBuilder();
byte[] ByteObject = SerializeBinary(Obj);
foreach (byte b in ByteObject)
{
sb.Append(((int)b).ToString());
sb.Append(",");
}
return sb.Remove(sb.Length-1,1).ToString();
}
private static object String2Object(string Value)
{
string[] V = Value.Split(new char[] { ',' },StringSplitOptions.RemoveEmptyEntries);
byte[] ByteObject = new byte[V.Length];
for(int i=0;i<ByteObject.Length;i++)
{
ByteObject[i] = Convert.ToByte(V[i]);
}
return DeserializeBinary(ByteObject);
}
#endregion
}
}
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.XPath;
namespace LuckerSoft
{
/// <summary>
/// 该XML文件操作类提供一系统自动完成的操作类.包括常用的数据读取,写入与删除.
/// 支持非字符型数据(即所有支持序列化的object类型)的操作.
/// 并具有文件或结点不存在时自动创建的功能.
/// 该类采用静态类设计,用类名直接调用其公有方法,主要适用于对XML文件中单个结点的操作
/// 作者:Lucker
/// 日期:2009年12月29日
/// 版本:1.0.0
/// </summary>
public static class MyXML
{
/// <summary>
/// 从指定的XML文件中读取指定路径下所有结点的值
/// </summary>
/// <param name="XMLFile">带路径的XML文件名</param>
/// <param name="Path">带路径的结点名</param>
/// <returns></returns>
public static string[] ReadNodes(string XMLFile, string Path)
{
string Values="";
XmlDocument xmldoc = CheckFileExit(XMLFile);
XmlNode Node = FindNode(xmldoc, Path);
foreach (XmlNode node in Node.ChildNodes)
{
Values += node.Name.ToString() + ",";
}
return Values.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
}
/// <summary>
/// 从指定的XML文件中读取指定路径下单个结点的值.当结点不存在时,根据所提供默认值自动创建.
/// </summary>
/// <param name="XMLFile"></param>
/// <param name="Path"></param>
/// <param name="DefaultValue">结点不存在时,提供的默认值</param>
/// <returns></returns>
public static string ReadNode(string XMLFile, string Path, string DefaultValue)
{
XmlDocument xmldoc = CheckFileExit(XMLFile);
XmlNode Node = FindNode(xmldoc, Path);
if (Node != null)
{
return Node.InnerText;
}
else
{
WriteNode(XMLFile, Path, DefaultValue);
return DefaultValue;
}
}
/// <summary>
/// 读取一个object类型的结点数据.
/// </summary>
/// <param name="XMLFile"></param>
/// <param name="Path"></param>
/// <param name="DefaultValue">object类型的数据实际上是经过序列化后转换成string保存在文件中的</param>
/// <returns></returns>
public static object ReadNode(string XMLFile, string Path, object DefaultValue)
{
//读出文件中的string值
string Value=ReadNode(XMLFile, Path, Object2String(DefaultValue));
//再将读取出来的string数据需要转化成object对象.
object o= String2Object(Value);
return o;
}
/// <summary>
/// 向指定的XML文件中写入指定路径的结点数据.当指定结点不存在是时,将沿路径依次创建各父结点
/// </summary>
/// <param name="XMLFile"></param>
/// <param name="Path"></param>
/// <param name="Value">结点值</param>
public static void WriteNode(string XMLFile, string Path, string Value)
{
XmlDocument myDoc = CheckFileExit(XMLFile);
PathNode = null;
PathDepth = 0;
ParentNode = null;
CheckPath(myDoc, Path);
XmlNode Node = FindNode(myDoc, Path);
if (Node != null)
{
UpdateXmlNode(Value, Node);
}
myDoc.Save(XMLFile);
}
/// <summary>
/// 写入一个object类型的对象.
/// </summary>
/// <param name="XMLFile"></param>
/// <param name="Path"></param>
/// <param name="Value"></param>
public static void WriteNode(string XMLFile, string Path, object Value)
{
//经序列化后转换成string型后再写入.
WriteNode(XMLFile, Path, Object2String(Value));
}
/// <summary>
/// 删除指定的结点
/// </summary>
/// <param name="XMLFile"></param>
/// <param name="Path"></param>
/// <returns></returns>
public static bool DeleteNode(string XMLFile, string Path)
{
XmlDocument myDoc = CheckFileExit(XMLFile);
XmlNode Node = FindNode(myDoc, Path);
if(Node!=null)
{
if (Node.ParentNode != null)
{
Node.ParentNode.RemoveChild(Node);
}
else
{
myDoc.RemoveChild(Node);
}
myDoc.Save(XMLFile);
}
return true;
}
#region 私有方法
/// <summary>
/// 更新指定结点的值
/// </summary>
/// <param name="TextName">结点的值</param>
/// <param name="XNe">要更新的结点</param>
/// <returns></returns>
private static bool UpdateXmlNode(string TextName, XmlNode XNe)
{
if (XNe != null)
{
XNe.InnerText = TextName;
return true;
}
else
return false;
}
/// <summary>
/// 插入一个指定的XML元素
/// </summary>
/// <param name="myDoc"></param>
/// <param name="ElementName">元素名</param>
/// <param name="Text">元素值</param>
/// <returns></returns>
private static XmlNode InsertXmlElement(XmlDocument myDoc, string ElementName, string Text)
{
if (ElementName != "")
{
XmlElement XEt = myDoc.CreateElement("",ElementName,"");
XEt.InnerText = Text;
return (XmlNode)XEt;
}
else
{
return null;
}
}
static string[] PathNode = null;
static int PathDepth=0;
static XmlNode ParentNode;
/// <summary>
/// 获取路径结点集指定深度的路径表示
/// </summary>
/// <param name="depth"></param>
/// <returns></returns>
private static string GetPath(int depth)
{
string path = "";
for (int i = 0; i < depth && i < PathNode.Length; i++)
{
path += PathNode[i] + "/";
}
return path.Substring(0,path.Length - 1);
}
/// <summary>
/// 递归检查指定路径上的结点是否存在,不存在则创建
/// </summary>
/// <param name="myDoc"></param>
/// <param name="Path"></param>
private static void CheckPath(XmlDocument myDoc, string Path)
{
if (PathNode == null)
{
PathNode = Path.Split(new char[] { '/' });
PathDepth = 0;
}
if (PathDepth < PathNode.Length)
{
string NewPath = GetPath(++PathDepth);
string Name = PathNode[PathDepth-1];
XmlNode Node = FindNode(myDoc, NewPath);
if (Node == null)
{
XmlNode NewNode = InsertXmlElement(myDoc, Name, null);
ParentNode.AppendChild(NewNode);
ParentNode = FindNode(myDoc, NewPath);
}
else
{
ParentNode = Node;
}
CheckPath(myDoc, NewPath);
}
}
/// <summary>
/// 查询指定路径上的第一个结点
/// </summary>
/// <param name="myDoc"></param>
/// <param name="Path"></param>
/// <returns></returns>
private static XmlNode FindNode(XmlDocument myDoc, string Path)
{
//Path:aaaa/bbbb/cccc
XmlNode myNode = myDoc.SelectSingleNode(Path);
if (!(myNode == null))
{
return myNode;
}
return null;
}
/// <summary>
/// 查询指定路径上的所有结点
/// </summary>
/// <param name="myDoc"></param>
/// <param name="Path"></param>
/// <returns></returns>
private static XmlNodeList FindNodes(XmlDocument myDoc, string Path)
{
//Path:aaaa/bbbb/cccc
XmlNodeList myNodeList = myDoc.SelectNodes(Path);
if (!(myNodeList == null))
{
return myNodeList;
}
return null;
}
/// <summary>
/// 查询指定的XML文件是否存在.如果不存在,则创建一个具有默认根结点的XML文件.
/// </summary>
/// <param name="XMLFile"></param>
/// <returns></returns>
private static XmlDocument CheckFileExit(string XMLFile)
{
XmlDocument xmldoc = new XmlDocument();
if (File.Exists(XMLFile))
{
try
{
xmldoc.Load(XMLFile);
}
catch (Exception ex)
{
throw new Exception("载入XML文件[" + XMLFile + "]失败.\r\n"+ex.Message);
}
}
else
{
XmlDeclaration xn = xmldoc.CreateXmlDeclaration("1.0", "gb2312", null);
xmldoc.AppendChild(xn);
XmlElement xmlelem = xmldoc.CreateElement("", "打印项目模板", "");
xmldoc.AppendChild(xmlelem);
xmldoc.Save(XMLFile);
}
return xmldoc;
}
/// <summary>
/// 序列化为二进制字节数组
/// </summary>
/// <param name="request">要序列化的对象</param>
/// <returns>字节数组</returns>
private static byte[] SerializeBinary(object request)
{
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter serializer = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
System.IO.MemoryStream memStream = new System.IO.MemoryStream();
serializer.Serialize(memStream, request);
return memStream.GetBuffer();
}
/// <summary>
/// 从二进制数组反序列化得到对象
/// </summary>
/// <param name="buf">字节数组</param>
/// <returns>得到的对象</returns>
private static object DeserializeBinary(byte[] buf)
{
System.IO.MemoryStream memStream = new MemoryStream(buf);
memStream.Position = 0;
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter deserializer =
new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
object newobj = deserializer.Deserialize(memStream);
memStream.Close();
return newobj;
}
private static string Object2String(object Obj)
{
StringBuilder sb = new StringBuilder();
byte[] ByteObject = SerializeBinary(Obj);
foreach (byte b in ByteObject)
{
sb.Append(((int)b).ToString());
sb.Append(",");
}
return sb.Remove(sb.Length-1,1).ToString();
}
private static object String2Object(string Value)
{
string[] V = Value.Split(new char[] { ',' },StringSplitOptions.RemoveEmptyEntries);
byte[] ByteObject = new byte[V.Length];
for(int i=0;i<ByteObject.Length;i++)
{
ByteObject[i] = Convert.ToByte(V[i]);
}
return DeserializeBinary(ByteObject);
}
#endregion
}
}
※※※※※※※※※※※※※※--我的程序人生--※※※※※※※※※※※※※※