之前操作XML文檔基本上用的是XmlDocument對象,對一些小文件的操作使用還挺順手,今天偶爾用來操作一個4M的XML文件,發現查詢指定的節點並刪除時執行時間很長。在Web項目下和控制台程序中都出現很長時間程序無響應,並且CPU占用很高。不知道是我寫的代碼有問題還是本身這個對象不適合操作打文件呢?我的代碼如下:
XmlDocument xmlDocument = new XmlDocument(); xmlDocument.Load(ConfigFilePath); XmlNodeList nodeList = xmlDocument.SelectNodes("/System/add"); foreach (XmlNode node in nodeList) { if (node.Attributes["key"] != null) { if (node.Attributes["key"].Value.Equals(key, StringComparison.CurrentCultureIgnoreCase)) { node.RemoveAll(); } } }
就是查詢根節點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毫秒左右,簡直不是一個數量級別的。
同樣的一個園友用以下方法實現刪除功能:
private static void DeleteXmlNodeInformation(string xmlPath) { try { //定義並從xml文件中加載節點(根節點) XElement rootNode = XElement.Load(xmlPath); //查詢語句: 獲取ID屬性值等於"999999"的所有User節點 IEnumerable<XElement> targetNodes = from target in rootNode.Descendants("User") where target.Attribute("ID").Value.Equals("999999") select target; //將獲得的節點集合中的每一個節點依次從它相應的父節點中刪除 targetNodes.Remove(); //保存對xml的更改操作 rootNode.Save(xmlPath); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } }
未通過調試,一直提示沒有父節點,不知道是怎么回事。下面給出詳細代碼:
//xml文件路徑 string ConfigFilePath = AppDomain.CurrentDomain.BaseDirectory + "Profile.config"; //初始化XElement對象 XElement rootNodes = XDocument.Load(ConfigFilePath).Root; rootNodes .Elements("add") //查詢根節點下所有add子節點 .Where( el => el.Attribute("value").Value //Where方法中用於篩選復核條件的節點 .Equals("d")) .First() //可以實現只刪第一條 .Remove();//刪除節點 //實現刪除查詢結果中指定索引的一個節點可以如下實現: rootNodes .Elements("add") //查詢根節點下所有add子節點 .Where( el => el.Attribute("value").Value //Where方法中用於篩選復核條件的節點 .Equals("d")) .Skip(10) //跳過指定的條數,這里可以實現刪除指定的某一個節點 .First() //跳過指定條數后獲取剩余的第一個節點 .Remove(); //刪除節點 rootNodes.Save(ConfigFilePath);//保存到文件
了解了LINQ才發現,這個功能確實很強大。
原文地址:http://www.cnblogs.com/lifeil/archive/2013/03/08/2950163.html