前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C#笔记:XmlHelper工具

C#笔记:XmlHelper工具

作者头像
超级大猪
发布2019-11-22 11:42:43
1.1K0
发布2019-11-22 11:42:43
举报
文章被收录于专栏:大猪的笔记大猪的笔记
代码语言:javascript
复制
  public static class XmlHelper
    {
        public static string toSafe(this string strValue)
        {
            if(!string.IsNullOrEmpty(strValue))
            {
                strValue = strValue.Replace("%", "%25");
                strValue = strValue.Replace("#", "%23");
                strValue = strValue.Replace("$", "%24");
            }          
            return strValue;
        }

        public static string toNormal(this string strValue)
        {           
            if(!string.IsNullOrEmpty(strValue))
            {
                strValue = strValue.Replace("%23", "#");
                strValue = strValue.Replace("%24", "$");
                strValue = strValue.Replace("%25", "%");               
            }           
            return strValue;
        }

      
        /// <summary>
        /// 创建xml文件,如果该文件存在则取消动作
        /// </summary>
        /// <param name="myXmlPath">创建的路径</param>
        /// <param name="rootName">根节点名称</param>
        public static void CreateXml(string myXmlPath, string rootName)
        {
            if (!File.Exists(myXmlPath))
            {
                XDocument xdoc = new XDocument(
                    new XElement(rootName)
                    );
                xdoc.Save(myXmlPath);
            }
        }
        /// <summary>
        /// 搜索一个带路径的节点
        /// </summary>
        /// <param name="myXmlPath">xml路径</param>
        /// <param name="path">
        /// 描述:节点路径
        /// 类型:string
        /// 表示:path1#path2 用#分层 root为空,path1为root下第一层的节点名称
        /// </param>
        /// <returns></returns>
        public static IEnumerable<XElement> Search(string myXmlPath, string path)
        {
            XElement rootNode = XElement.Load(myXmlPath);
            var query = Search(rootNode, path);
            return query;
        }

        /// <summary>
        /// 搜索一个带路径和目标属性值的节点
        /// </summary>
        /// <param name="myXmlPath">xml路径</param>
        /// <param name="path">
        /// 描述:节点路径
        /// 类型:string
        /// 表示:path1#path2 用#分层 root为空,path1为root下第一层的节点名称
        /// </param>
        /// <param name="attrNameValue">
        /// 描述:查找的属性值,允许传入多个属性and查找
        /// 类型:string
        /// 格式:id#123$name#1 或 id#123
        /// </param>
        /// <returns></returns>
        public static IEnumerable<XElement> Search(string myXmlPath, string path, string attrNameValue)
        {
            XElement rootNode = XElement.Load(myXmlPath);
            var query = Search(rootNode, path, attrNameValue);
            return query;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="rootNode">传入的根节点</param>
        /// <param name="path">xml文件路径</param>
        /// <param name="attrNameValue">
        /// 描述:用于查找的属性。可以为多个。
        /// 格式:id#1$name#王大锤
        /// </param>
        /// <returns></returns>
        private static IEnumerable<XElement> Search(XElement rootNode, string path, string attrNameValue)
        {
            try
            {
                var query = Search(rootNode, path);

                string[] attrInfo = attrNameValue.Split('$');

                //下面使用表达式树查询多个属性
                IQueryable<XElement> queryableData = query.AsQueryable<XElement>();

                ParameterExpression pe = Expression.Parameter(typeof(XElement), "node");

                Expression expression = Expression.Constant(true);

                foreach (var item in attrInfo)
                {
                    string[] attrValueName = item.Split('#');
                    Expression attrName = Expression.Constant((XName)attrValueName[0]);

                    var method = typeof(XElement).GetMethod("Attribute");

                    Expression left = Expression.Call(pe,
                       method, attrName);//Attribute(attrName)

                    Expression leftValue = Expression.Property(left, typeof(XAttribute).GetProperty("Value"));//Attribute(attrName).Value
                    Expression right = Expression.Constant(attrValueName[1]);
                    Expression e1 = Expression.Equal(leftValue, right);//Attribute(attrName).Value == attrValue

                    expression = Expression.And(e1, expression);
                }


                MethodCallExpression whereCallExpression = Expression.Call(
                    typeof(Queryable),
                    "Where",
                    new Type[] { queryableData.ElementType },
                    queryableData.Expression,
                    Expression.Lambda<Func<XElement, bool>>(expression, new ParameterExpression[] { pe })

                    );
                query = query.Where(o => o.Attribute(attrInfo[0]).Value == attrInfo[1]);
                IQueryable<XElement> results = queryableData.Provider.CreateQuery<XElement>(whereCallExpression);

                return results;
            }
            catch
            {
                return new List<XElement>();
            }
        }

        private static IEnumerable<XElement> Search(XElement rootNode, string path)
        {
            string[] paths = path.Split('#');

            IEnumerable<XElement> query = rootNode.Elements().Where(x => x.Name == paths[0]);

            for (int i = 1; i < paths.Length; i++)
            {
                string keyword = paths[i];
                query = query.Elements().Where(p => p.Name == keyword);
            }

            return query;
        }

        private readonly static object _AddNodeLock = new object();
        /// <summary>
        /// 增加一个节点,找到要增加的父节点,然后添加
        /// </summary>
        /// <param name="myXmlPath">xml文档路径</param>
        /// <param name="path">父节点路径</param>
        /// <param name="newNode">
        /// 描述:新节点
        /// 类型:string
        /// 格式:nodeName$attr1=attrValue1#attr2=attrValue2$nodeValue
        /// </param>
        public static void AddNode(string myXmlPath, string path, string newNode)
        {
            lock(_AddNodeLock)
            {
                string[] mainNode = newNode.Split('$');

                XElement tempNode = new XElement(mainNode[0]);

                if (mainNode[1] != "")
                {
                    string[] attrNameValue = mainNode[1].Split('#');

                    //下面增加属性
                    foreach (var item in attrNameValue)
                    {
                        string[] tempAttr = item.Split('=');
                        tempNode.SetAttributeValue(tempAttr[0], tempAttr[1]);
                    }
                }

                tempNode.SetValue(mainNode[2]);


                XElement rootNode = XElement.Load(myXmlPath);

                XElement findNode;
                if (string.IsNullOrEmpty(path))
                {
                    findNode = rootNode;
                }
                else
                {
                    findNode = Search(rootNode, path).FirstOrDefault();
                }

                findNode.Add(tempNode);
                rootNode.Save(myXmlPath);
            }          
        }

        /// <summary>
        /// 删除一个带路径的节点
        /// </summary>
        /// <param name="myXmlPath">文件路径</param>
        /// <param name="path">
        /// 描述:文件节点路径
        /// 类型:string
        /// 格式:path1#path2 用#分层 root为空,path1为root下第一层的节点名称
        /// </param>
        public static void RemoveNode(string myXmlPath, string path)
        {
            XElement rootNode = XElement.Load(myXmlPath);
            var targetNodes = Search(rootNode, path);
            targetNodes.Remove();
            rootNode.Save(myXmlPath);
        }

        /// <summary>
        /// 通过属性和层次路径删除节点
        /// </summary>
        /// <param name="myXmlPath">xml物理路径</param>
        /// <param name="path">节点层次路径</param>
        /// <param name="attrNameValue">
        /// 描述:查找的属性值,允许传入多个属性and查找
        /// 类型:string
        /// 格式:id#123$name#1 或 id#123
        /// </param>
        public static void RemoveNode(string myXmlPath, string path, string attrNameValue)
        {
            if (string.IsNullOrEmpty(attrNameValue))
            {
                RemoveNode(myXmlPath, path);
                return;
            }
            XElement rootNode = XElement.Load(myXmlPath);
            var targetNodes = Search(rootNode, path, attrNameValue);
            targetNodes.Remove();
            rootNode.Save(myXmlPath);
        }

        /// <summary>
        /// 通过层次和属性查找节点,并修改节点信息
        /// </summary>
        /// <param name="myXmlPath">xml物理路径</param>
        /// <param name="path">节点的层次路径</param>
        /// <param name="attrNameValue">
        /// 描述:查找的属性值,允许传入多个属性and查找
        /// 类型:string
        /// 格式:id#123$name#1 或 id#123
        /// </param>
        /// <param name="newAttrNameValue">
        /// 描述:新增添的属性值,允许一次添加多个属性
        /// 类型:string
        /// 格式:id#123$name#1 或 id#123
        /// </param>
        /// <param name="newValue"></param>
        public static void Modifiy(string myXmlPath, string path, string attrNameValue, string newAttrNameValue, string newValue)
        {
            XElement rootNode = XElement.Load(myXmlPath);
            var targetNode = Search(rootNode, path, attrNameValue).FirstOrDefault();

            if (targetNode == null)
            {
                return;
            }

            if (!string.IsNullOrEmpty(newAttrNameValue))
            {
                string[] allAttr = newAttrNameValue.Split('$');

                foreach (var item in allAttr)
                {
                    string[] attr = item.Split('#');
                    targetNode.SetAttributeValue(attr[0], attr[1]);
                    if (attr[1] == "null")
                    {
                        targetNode.Attribute(attr[0]).Remove();
                    }
                }
            }

            if (!string.IsNullOrEmpty(newValue))
            {
                if (newValue == "null")
                {
                    targetNode.SetValue("");
                }
                else
                {
                    targetNode.SetValue(newValue);
                }
            }

            rootNode.Save(myXmlPath);
        }
    }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015-09-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档