C#笔记:XmlHelper工具
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); } }