zoukankan      html  css  js  c++  java
  • C#下通过LINQ实现对XML文档指定节点的删除操作

    之前操作XML文档基本上用的是XmlDocument对象,对一些小文件的操作使用还挺顺手,今天偶尔用来操作一个4M的XML文件,发现查询指定的节点并删除时执行时间很长。在Web项目下和控制台程序中都出现很长时间程序无响应,并且CPU占用很高。不知道是我写的代码有问题还是本身这个对象不适合操作打文件呢?我的代码如下:

     1 XmlDocument xmlDocument = new XmlDocument();
     2 xmlDocument.Load(ConfigFilePath);
     3 XmlNodeList nodeList = xmlDocument.SelectNodes("/System/add");
     4 foreach (XmlNode node in nodeList)
     5 {
     6     if (node.Attributes["key"] != null)
     7     {
     8         if (node.Attributes["key"].Value.Equals(key, StringComparison.CurrentCultureIgnoreCase))
     9         {
    10             node.RemoveAll();
    11             
    12         }
    13     }
    14 }

    就是查询根节点System下add子节点,如果该节点的key属性和指定的属性相等,则删除此节点。经过运行发现,我的一个4M大的文件大概1万个节点,执行起来一直无响应。希望高手能给个解答。

    后来考虑到是操作XML文件,于是想起用LINQ TO XML来实现,同样的功能我实现如下:

    XElement rootNodes = XDocument.Load(ConfigFilePath).Root;
    rootNodes.Elements("add").Where(el => el.Attribute("key").Value.Equals(key)).Remove();
    

     

    经测试,该方法指定时间仅仅在200毫秒左右,简直不是一个数量级别的。

    同样的一个园友用以下方法实现删除功能:

     1 private static void DeleteXmlNodeInformation(string xmlPath)
     2 {
     3     try
     4     {
     5         //定义并从xml文件中加载节点(根节点)
     6         XElement rootNode = XElement.Load(xmlPath);
     7         //查询语句: 获取ID属性值等于"999999"的所有User节点
     8         IEnumerable<XElement> targetNodes = from target in rootNode.Descendants("User")
     9                                             where target.Attribute("ID").Value.Equals("999999")
    10                                             select target;
    11 
    12         //将获得的节点集合中的每一个节点依次从它相应的父节点中删除
    13         targetNodes.Remove();
    14         //保存对xml的更改操作
    15         rootNode.Save(xmlPath);
    16     }
    17     catch (Exception ex)
    18     {
    19         Console.WriteLine(ex.ToString());
    20     }
    21 }

    未通过调试,一直提示没有父节点,不知道是怎么回事。下面给出详细代码:

     1 //xml文件路径
     2 string ConfigFilePath = AppDomain.CurrentDomain.BaseDirectory + "Profile.config";
     3 //初始化XElement对象
     4 XElement rootNodes = XDocument.Load(ConfigFilePath).Root;
     5 
     6 rootNodes
     7     .Elements("add") //查询根节点下所有add子节点
     8     .Where(
     9         el =>
    10             el.Attribute("value").Value //Where方法中用于筛选复核条件的节点
    11             .Equals("d"))
    12      .First() //可以实现只删第一条
    13      .Remove();//删除节点
    14 
    15 //实现删除查询结果中指定索引的一个节点可以如下实现:
    16 rootNodes
    17     .Elements("add") //查询根节点下所有add子节点
    18     .Where(
    19         el =>
    20             el.Attribute("value").Value //Where方法中用于筛选复核条件的节点
    21             .Equals("d"))
    22      .Skip(10)  //跳过指定的条数,这里可以实现删除指定的某一个节点
    23      .First()   //跳过指定条数后获取剩余的第一个节点
    24      .Remove(); //删除节点
    25 
    26 rootNodes.Save(ConfigFilePath);//保存到文件
  • 相关阅读:
    run C source file like a script
    shared_ptr注意点
    C++ #if #endif #define #ifdef #ifndef #if defined #if !defined详解 (转)
    linux切换g++
    std::forward_list
    有关typename
    win7下 mysql安装(mysql-5.7.18-winx64.zip)
    c++ 库函数返回的字符串指针是否需要手动释放
    c++ const char *[] or char [][]
    校园资源助手
  • 原文地址:https://www.cnblogs.com/existcQ/p/2952618.html
Copyright © 2011-2022 走看看