2008-12-17 06:47 P.M.
最近忽然想把过去写的IPMSG更新一下,把聊天记录部分改用linq实现,感觉确实比DOM直观多了,写下来希望对新手有帮助,linq to XML 所用的类都封装在System.Xml.Linq下,下面的例子还会需要System.Linq
首先创建log文件 string strNow = DateTime.Now.ToString("yyyyMMddhhmmss"); FileInfo fiXML = new FileInfo(@"XML\xmlLog.xml"); //如果文件不存在 if (!(fiXML.Exists)) { //创建xml文档 XDocument xelLog =new XDocument( new XDeclaration("1.0", "utf-8", "no"), new XElement("ipmsg", new XElement("msg_log", new XElement("user", "Bin"), new XElement("logdate", strNow), new XElement("message", "一条xml linq测试") ) ) ); xelLog.Save(@"XML\xmlLog.xml"); } 如果要给元素加属性用XAttribute,和子节点一起做参数传进去,比如在这里我们想给每条聊天记录都加一个ID: new XAttribute("logid", "00001"), 输出文档如下: <?xml version="1.0" encoding="utf-8" standalone="no"?> <netmsg> <msg_log logid="00001"> <user>Bin</user> <logdate>20081217090733</logdate> <message>一条xml linq测试</message> </msg_log> </netmsg> 当然也可以用元素的形式表示ID,个人习惯问题,属性和元素功能基本是一样的,可以互相转换。 一、检索记录 首先要有检索功能,查看全部聊天记录: Array queryXML = LinqHeper.getXmlLOGInFo(); 返回Array,自己随意处理,比如: dgvStudent.DataSource = queryXML; 下面是getXmlLOGInFo方法: //实例化XMLog XElement xelem = XElement.Load(@"XML\xmlLog.xml"); //执行linq检索(xmlLOG) var queryXML = from xmlLog in xelem.Descendants("msg_log") //条件都加在这里,注意条件用双等,多条件用 && 连接 //用户名是Bin的所有记录 //where xmlLog.Element("user").Value == "Bin" select new { 用户名 = xmlLog.Element("user").Value.ToUpper() , 时间 = xmlLog.Element("logdate").Value , 消息 = xmlLog.Element("message").Value }; return queryXML.ToArray(); 上边的语句也可以写成lambda表达式的形式(其实就是"=>"前是参数,后面是返回值) var queryXML = xelem.Descendants("msg_log") .Where(x =>( x.Element("logid").Value == "1334255" && x.Element("user").Value == "bin")) .Select(x => new { 用户名 = x.Element("user").Value.ToUpper() , 时间 = x.Element("logdate").Value , 消息 = x.Element("message").Value }); 不过还是比较推荐前面写的方法,比较直观,方便维护(在这个例子中lambda表达式没有很大优势,一般情况,还是可以减少很多代码的) 注:如果想分页就用Skip与Take方法,比如queryXML.Skip(45).Take(15)就是第四页(我没有用dgv) 二、添加记录 下面需要用到System.Collections.Generic strNow = DateTime.Now.ToString("yyyyMMddhhmmss"); Dictionary<string,string> dicLog = new Dictionary<string,string>(); dicLog.Add("user", "Bin"); dicLog.Add("logdate", strNow); dicLog.Add("message", "这是一条添加记录测试"); LinqHeper.insLog(dicLog); insLog方法: //实例化XMLog XElement xelem = XElement.Load(@"XML\xmlLog.xml"); //执行linq添加(xmlLOG) XElement newLog = new XElement("msg_log", new XElement("user", (string)dicLog["user"]), new XElement("logdate", (string)dicLog["logdate"]), new XElement("message", (string)dicLog["message"]) ); xelem.Add(newLog); //保存xml xelem.Save(@"XML\xmlLog.xml"); 三、修改记录 如果一个朋友换了一个用户名,我们希望可以把他现在和过去的聊天记录在一起显示,就要把过去的名字全换成现在的新名,例子: var queryXML = from xmlLog in xelem.Descendants("msg_log") //所有名字为Bin的记录 where xmlLog.Element("user").Value == "Bin" select xmlLog; foreach (XElement el in queryXML) { el.Element("user").Value = "LiuBin";//开始修改 } 四、删除记录 。。这种软件应该没有必要删除聊天记录,但是既然标题是增查删改,就硬加上了,如果觉得记录占的地方太大了,我们想把2008年1月1日(或1个月前)以前的记录全部删除,就用如下方法: //实例化XMLog XElement xelem = XElement.Load(@"XML\xmlLog.xml"); var queryXML = from xmlLog in xelem.Descendants("msg_log") where Convert.ToInt32(xmlLog.Element("logdate").Value) < 20080101010101 select xmlLog; queryXML.Remove(); xelem.Save(@"XML\xmlLog.xml"); |