C#笔记:XmlHelper工具

  • 2019 年 11 月 22 日
  • 笔记

  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);          }      }