C#读写XML文件工具类——满足一切需求

      还是由于工作的需要,要进行解析XML配置表,虽然感觉XML很简单,因为之前对XML完全空白,所以只能从头学起,那就只能从google开始,找到一些参考①②③见文末,但是总感觉比较零散、混乱,功能不全,只能是例子不能成为工具,所以一直想找一个基本可以满足所有需求的实现。大概熟悉了XML的结构(还是花了好久,虽然比较简单,但是要很C#api中的Node,Element,Attribute等概念对应分得清要一点时间去消化)和C# XmlDocument的api,感觉通过api去实现一些功能还是比较困难或者比较直观,比如我要查找含有属性“lang”的所有结点,这个大概想了下要得遍历,所以迟迟未动手,知道我找到参考④。看了④的文章,很是惊奇,惊呼——原来还有这个东西(Xpath),顿时觉得希望实现自己想要的功能。然后就去查阅W3C School的Xpath的规范。

       有了想法之后,总是忍不住的想动手,刚开始的想法是定义一个StringBuilder xpath变量,然后往后面添加相关操作的Xpath字符串,但是还是感觉情况太多了,函数命名都成问题了(我记得一直命名到AddNode9()),总感觉做的是字符匹配的过程,但是有没有“正则表达式”的智能,然后我有想起一直的困惑——对于情况很多再加上不同情况的组合的问题解决起来很被动,有种被耍的感觉。那只有彻底解决,其实这就是“正则表达式”的原理——有限状态机,好在我之前看过“有限状态机”的理论。

       我早上三点起来(哎,一直挺矛盾的),我在CodeProject上找FSM的代码(还真不少),果断下载了几个,对代码仔细研读一番,最后感觉这个问题用FSM实在是大材小用,发现之前感觉的“不智能”都不会了,可以通过约束使用规范避免,所以还是回归到Xpath上,然后就有了下面的代码(测试了几个都没有问题),后面部分(有注释的直接copy③),实在是没有时间(一会还要去上班),然后就是功能还不完善,以后有时间一并补上(如果你有补充希望能够分享下,谢谢)。

下面的代码(假定你具有Xpath的基础)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
/// Code By D.S.Qiu
namespace XmlParse
{
    class XmlUtils
    {
        public static StringBuilder xpath = new StringBuilder();
        public static XmlDocument xmlDoc=new XmlDocument();
        public static XmlElement root = null;
        public static void AddCommint(string commit)
        {
            xpath.Append(commit);
        }
        public static void AddNode(string name)
        {
            xpath.Append("/" + name);
        }
        public static void AddNodeRegardlessPosition(string name)
        {
            xpath.Append("//" + name);
        }
        public static void AddNodeByIndex(string name, string index)
        {
            xpath.Append("/" + name + "[" + index + "]");
        }
        public static void AddNodeByIndexRegardlessPosition(string name, string index)
        {
            xpath.Append("//" + name + "[" + index + "]");
        }
        public static void AddNodeByValue(string name, string value, string operatorstr = "=")
        {
            xpath.Append("[" + name + operatorstr + value + "]");
        }
        public static void AddIndex(string index)
        {
            xpath.Append("[" + index + "]");
        }
        public static void AddAttribute(string name)
        {
            xpath.Append("[@" + name + "]");
        }
        public static void AddAttributeByValue(string name,  string value,string operatorstr="=")
        {
            xpath.Append("[@" + name +operatorstr+value+ "]");
        }
        public static void AddAnyNode()
        {
            xpath.Append("/*" );
        }
        public static void AddAnyNodeRegardlessPosition()
        {
            xpath.Append("//*");
        }
        public static void AddAnyAttribute()
        {
            xpath.Append("[@*]");
        }
        public static void Load(string filename)
        {
            xmlDoc.Load(filename);
            root = xmlDoc.DocumentElement;
        }

        public static XmlNodeList Commit(string commit=null)
        {
            XmlNodeList xn=null;
            if (commit != null)
            {
                  xn= root.SelectNodes(commit);
            }

            else if (xpath.Length != 0)
            {
                xn= root.SelectNodes(XmlUtils.xpath.ToString());
                xpath.Clear();
            }
            
            return xn;
        }
        public void addElement(string path, string node_root, string node_name, string node_text, string att_name, string att_value)
        {
            Load(path);
 
            XmlNodeList nodeList = xmlDoc.SelectSingleNode(node_root).ChildNodes;//获取bookstore节点的所有子节点
            //判断是否有节点,有节点就遍历所有子节点,看看有没有重复节点,没节点就添加一个新节点
            if (nodeList.Count > 0)
            {
                foreach (XmlNode xn in nodeList)//遍历所有子节点 
                {
                    XmlElement xe = (XmlElement)xn;//将子节点类型转换为XmlElement类型 
                    if (xe.GetAttribute(att_name) != att_value)
                    {
                        XmlNode xmldocSelect = xmlDoc.SelectSingleNode(node_root);   //选中根节点
                        XmlElement son_node = xmlDoc.CreateElement(node_name);    //添加子节点 
                        son_node.SetAttribute(att_name, att_value);     //设置属性
                        son_node.InnerText = node_text;    //添加节点文本
                        xmldocSelect.AppendChild(son_node);       //添加子节点
                        xmlDoc.Save(path);          //保存xml文件
                        break;
                    }
                }
 
            }
            else
            {
                XmlNode xmldocSelect = xmlDoc.SelectSingleNode(node_root);   //选中根节点
                XmlElement son_node = xmlDoc.CreateElement(node_name);    //添加子节点 
                son_node.SetAttribute(att_name, att_value);     //设置属性
                son_node.InnerText = node_text;    //添加节点文本
                xmldocSelect.AppendChild(son_node);       //添加子节点
                xmlDoc.Save(path);          //保存xml文件
            }
        }
 
        /// <summary>
        /// 修改节点的内容
        /// </summary>
        /// <param name="path">xml文件的物理路径</param>
        /// <param name="node_root">根节点名称</param>
        /// <param name="new_text">节点的新内容</param>
        /// <param name="att_name">节点的属性名</param>
        /// <param name="att_value">节点的属性值</param>
        public void UpdateElement(string path, string node_root, string new_text, string att_name, string att_value)
        {
            Load(path);
            XmlNodeList nodeList = xmlDoc.SelectSingleNode(node_root).ChildNodes;//获取bookstore节点的所有子节点 
            foreach (XmlNode xn in nodeList)//遍历所有子节点 
            {
                XmlElement xe = (XmlElement)xn;//将子节点类型转换为XmlElement类型 
                if (xe.GetAttribute(att_name) == att_value)
                {
                    xe.InnerText = new_text;    //内容赋值
                    xmlDoc.Save(path);//保存 
                    break;
                }
            }
 
        }
 
        /// <summary>
        /// 删除节点
        /// </summary>
        /// <param name="path">xml文件的物理路径</param>
        /// <param name="node_root">根节点名称</param>
        /// <param name="att_name">节点的属性名</param>
        /// <param name="att_value">节点的属性值</param>
        public void deleteNode(string path, string node_root, string att_name, string att_value)
        {
            Load(path);
            XmlNodeList nodeList = xmlDoc.SelectSingleNode(node_root).ChildNodes;
            XmlNode root = xmlDoc.SelectSingleNode(node_root);
            foreach (XmlNode xn in nodeList)
            {
                XmlElement xe = (XmlElement)xn;
                if (xe.GetAttribute(att_name) == att_value)
                {
                    //xe.RemoveAttribute("name");//删除name属性 
                    xe.RemoveAll();//删除该节点的全部内容 
                    root.RemoveChild(xe);
                    xmlDoc.Save(path);//保存 
                    break;
                }
 
            }
        }
    }
}
        

         最后说下自己的感悟:因为刚毕业,工作中的很多问题都没有接触过,虽然都很简单,但是要做出来还是要花一定时间的,所以D.S.Qiu觉得学一个新东西一定要彻底弄懂,以后才能事半功倍,还要记录一些学习过程中遇到的问题和解决问题的一些方法和心得。

        如果您对D.S.Qiu有任何建议或意见可以在文章后面评论,或者发邮件(gd.s.qiu@gmail.com)交流,您的鼓励和支持是我前进的动力,希望能有更多更好的分享。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值