博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

C# XML操作类2:xmlHelper例子

Posted on 2012-07-07 10:55  oilsun  阅读(543)  评论(0编辑  收藏  举报

http://mcgtts.iteye.com/blog/798926

首先,看下这个XmlHelper类库的结构,如下图:

然后,在Vs中新建一个解决方案,叫做XMLHelper,添加一个C# 类库项目XMLHelper,重命名Class1.cs为XmlHelper.cs。

再为XmlHelper.cs添加

using System.Collections;
using System.Xml;

这两个引用保证了我们可以使用XML的大部分功能和哈希表.

主要的代码如下:


 

namespace XMLHelper
{
    public class XmlHelper
    {
        #region 公共变量
        XmlDocument xmldoc;
        XmlNode xmlnode;
        XmlElement xmlelem;
        #endregion

        #region 创建Xml文档
        /// <summary>
        /// 创建一个带有根节点的Xml文件
        /// </summary>
        /// <param name="FileName">Xml文件名称</param>
        /// <param name="rootName">根节点名称</param>
        /// <param name="Encode">编码方式:gb2312,UTF-8等常见的</param>
        /// <param name="DirPath">保存的目录路径</param>
        /// <returns></returns>
        public bool CreateXmlDocument(string FileName, string rootName, string Encode)
        {
            try
            {
                xmldoc = new XmlDocument();
                XmlDeclaration xmldecl;
                xmldecl = xmldoc.CreateXmlDeclaration("1.0", Encode, null);
                xmldoc.AppendChild(xmldecl);
                xmlelem = xmldoc.CreateElement("", rootName, "");
                xmldoc.AppendChild(xmlelem);
                xmldoc.Save(FileName);
                return true;
            }
            catch (Exception e)
            {
                return false;
                throw new Exception(e.Message);
            }
        }

        #endregion

        #region 常用操作方法(增删改)
        /// <summary>
        /// 插入一个节点和它的若干子节点
        /// </summary>
        /// <param name="XmlFile">Xml文件路径</param>
        /// <param name="NewNodeName">插入的节点名称</param>
        /// <param name="HasAttributes">此节点是否具有属性,True为有,False为无</param>
        /// <param name="fatherNode">此插入节点的父节点</param>
        /// <param name="htAtt">此节点的属性,Key为属性名,Value为属性值</param>
        /// <param name="htSubNode">子节点的属性,Key为Name,Value为InnerText</param>
        /// <returns>返回真为更新成功,否则失败</returns>
        public bool InsertNode(string XmlFile, string NewNodeName, bool HasAttributes, string fatherNode, Hashtable htAtt, Hashtable htSubNode)
        {
            try
            {
                xmldoc = new XmlDocument();
                xmldoc.Load(XmlFile);
                XmlNode root = xmldoc.SelectSingleNode(fatherNode);
                xmlelem = xmldoc.CreateElement(NewNodeName);

                if (htAtt != null && HasAttributes)//若此节点有属性,则先添加属性
                {
                    SetAttributes(xmlelem, htAtt);

                    SetNodes(xmlelem.Name, xmldoc, xmlelem, htSubNode);//添加完此节点属性后,再添加它的子节点和它们的InnerText

                }
                else
                {
                    SetNodes(xmlelem.Name, xmldoc, xmlelem, htSubNode);//若此节点无属性,那么直接添加它的子节点
                }

                root.AppendChild(xmlelem);
                xmldoc.Save(XmlFile);

                return true;
            }
            catch (Exception e)
            {

                throw new Exception(e.Message);

            }
        }
        /// <summary>
        /// 更新节点
        /// </summary>
        /// <param name="XmlFile">Xml文件路径</param>
        /// <param name="fatherNode">需要更新节点的上级节点</param>
        /// <param name="htAtt">需要更新的属性表,Key代表需要更新的属性,Value代表更新后的值</param>
        /// <param name="htSubNode">需要更新的子节点的属性表,Key代表需要更新的子节点名字Name,Value代表更新后的值InnerText</param>
        /// <returns>返回真为更新成功,否则失败</returns>
        public bool UpdateNode(string XmlFile, string fatherNode, Hashtable htAtt, Hashtable htSubNode)
        {
            try
            {
                xmldoc = new XmlDocument();
                xmldoc.Load(XmlFile);
                XmlNodeList root = xmldoc.SelectSingleNode(fatherNode).ChildNodes;
                UpdateNodes(root, htAtt, htSubNode);
                xmldoc.Save(XmlFile);
                return true;
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }

        /// <summary>
        /// 删除指定节点下的子节点
        /// </summary>
        /// <param name="XmlFile">Xml文件路径</param>
        /// <param name="fatherNode">制定节点</param>
        /// <returns>返回真为更新成功,否则失败</returns>
        public bool DeleteNodes(string XmlFile, string fatherNode)
        {
            try
            {
                xmldoc = new XmlDocument();
                xmldoc.Load(XmlFile);
                xmlnode = xmldoc.SelectSingleNode(fatherNode);
                xmlnode.RemoveAll();
                xmldoc.Save(XmlFile);
                return true;
            }
            catch (XmlException xe)
            {
                throw new XmlException(xe.Message);
            }
        }
        #endregion

        #region 私有方法
        /// <summary>
        /// 设置节点属性
        /// </summary>
        /// <param name="xe">节点所处的Element</param>
        /// <param name="htAttribute">节点属性,Key代表属性名称,Value代表属性值</param>
        private void SetAttributes(XmlElement xe, Hashtable htAttribute)
        {
            foreach (DictionaryEntry de in htAttribute)
            {
                xe.SetAttribute(de.Key.ToString(), de.Value.ToString());
            }
        }
        /// <summary>
        /// 增加子节点到根节点下
        /// </summary>
        /// <param name="rootNode">上级节点名称</param>
        /// <param name="XmlDoc">Xml文档</param>
        /// <param name="rootXe">父根节点所属的Element</param>
        /// <param name="SubNodes">子节点属性,Key为Name值,Value为InnerText值</param>
        private void SetNodes(string rootNode, XmlDocument XmlDoc, XmlElement rootXe, Hashtable SubNodes)
        {
            foreach (DictionaryEntry de in SubNodes)
            {
                xmlnode = XmlDoc.SelectSingleNode(rootNode);
                XmlElement subNode = XmlDoc.CreateElement(de.Key.ToString());
                subNode.InnerText = de.Value.ToString();
                rootXe.AppendChild(subNode);
            }
        }
        /// <summary>
        /// 更新节点属性和子节点InnerText值
        /// </summary>
        /// <param name="root">根节点名字</param>
        /// <param name="htAtt">需要更改的属性名称和值</param>
        /// <param name="htSubNode">需要更改InnerText的子节点名字和值</param>
        private void UpdateNodes(XmlNodeList root, Hashtable htAtt, Hashtable htSubNode)
        {
            foreach (XmlNode xn in root)
            {
                xmlelem = (XmlElement)xn;
                if (xmlelem.HasAttributes)//如果节点如属性,则先更改它的属性
                {
                    foreach (DictionaryEntry de in htAtt)//遍历属性哈希表
                    {
                        if (xmlelem.HasAttribute(de.Key.ToString()))//如果节点有需要更改的属性
                        {
                            xmlelem.SetAttribute(de.Key.ToString(), de.Value.ToString());//则把哈希表中相应的值Value赋给此属性Key
                        }
                    }
                }
                if (xmlelem.HasChildNodes)//如果有子节点,则修改其子节点的InnerText
                {
                    XmlNodeList xnl = xmlelem.ChildNodes;
                    foreach (XmlNode xn1 in xnl)
                    {
                        XmlElement xe = (XmlElement)xn1;
                        foreach (DictionaryEntry de in htSubNode)
                        {
                            if (xe.Name == de.Key.ToString())//htSubNode中的key存储了需要更改的节点名称,
                            {
                                xe.InnerText = de.Value.ToString();//htSubNode中的Value存储了Key节点更新后的数据
                            }
                        }
                    }
                }

            }
        }
        #endregion
    }
}


文章来自学IT网:http://www.xueit.com/html/2009-08/21_4275_00.html

下面讲解此类:

1、插入节点函数中的两个哈希表说明:

a.htAtt:用于存储了节点属性的哈希表,表中的Key对应了节点的属性名称,如<Fan Nickname="Jacky">这里的Nickname就是哈希表中的Key值,而Jacky就对应哈希表中的Value值,这样,你可以在插 入节点前,把该节点的属性(多个)名称和对应的值先存入哈希表中,然后再传给函数即可增加多个属性。

b.htSubNode:存储了子节点的数据,子节点包括他的名字和InnerText值,如<Age>23</Age>这里的Age就是子节点名字,23就是节点的InnerText值。

2、修改节点函数中的哈希表说明:

a.htAtt:存储了待更新的属性值,传入函数后,函数将逐一对比,查看节点中是否含有htAtt的Key值,如果含有,则表明节点的该属性的值(Value)将被htAtt中相应的Value替换。

b.htSubNode:存储了子节点的修改信息,传入函数后,函数将逐一对比,查看子节点的节点名字是否含有htSubNode的Key值,如果含有,则表明此子节点需要被更新,则此节点的InnerText将被修改为相应的htSubNode的Value值。

好了,下面我们来看看类库运行起来的效果吧:

一、先创建Xml文件,如下:

 

我们来这个路径下,打开刚才创建的xml文档,内容如下:

 

<?xml version="1.0" encoding="utf-8"?>
<AppSettings/>

 

 

二、执行插入节点操作,如下图:(插入的节点数据在程序中,请稍候在本文尾部下载)

我们再打开这个文件,看看插入效果和程序中的一样么:

<?xml version="1.0" encoding="utf-8"?>
<AppSettings>
  <Fan Nickname="Jacky">
    <Age>23</Age>
  </Fan>
</AppSettings>

 

三、我们修改一下节点内容:

 

修改效果如下:

<?xml version="1.0" encoding="utf-8"?>
<AppSettings>
  <Fan Nickname="Doggy">
    <Age>3</Age>
  </Fan>
</AppSettings>

 

四、好了,删除刚才的那些节点吧:


又变回原样了:

 

<?xml version="1.0" encoding="utf-8"?>
<AppSettings/>

 

OK,这就是这个Helper的主要功能,你可以重载一些函数,增加它的功能,让它更加健壮,这回我就多了个帮手了,呵呵,可以根据自己需求更改,以后就不怕写Xml了,当然,你也可以把它移植到移动项目中,同样可行,只是到时候请注意路径问题,最好使用绝对路径!


文章来自学IT网:http://www.xueit.com/cshare/show-4275-2.aspx