LinqToXML高级编程体验篇

【菜科解读】
首先,我们在Linq初级班 Linq To XML体验(基础)和Linq初级班 Linq To XML体验(编程篇)了解了一些XML的基本知识以及如何用LINQ to XML对XML文档进行简单的操作,本文将继续深入LINQ to XML,做一些高级编程的演示.我也是LINQ的初学者,文章中不免会有一些不对的地方,希望高手们多多指点,为我们LINQ初学者们多提宝贵的意见,我也会继续努力的,本文章目录如下所示:目录1.Linq to XML函数构造2.Linq to XML批注3.Linq to XML轴4.Linq to XML事件1.Linq to XML函数构造函数构造是指通过单个语句构建XML树的能力.在Linq初级班 Linq To XML体验(编程篇)中我们已经体验了如何使用XElement和XAttribute类手工创建XML树,也可以通过其他XElement和XAttribute对象传递给XElement类的构造函数来创建子元素和属性,也就是说,LINQ查询的结果可以用来创建XML树,下面就来看看一个演示:代码 //-----------------------------------------------------------// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .//-----------------------------------------------------------using System;using System.Xml.Linq;using System.Linq;namespace ConsoleApplication1{ class Program { static void Main(string[] args) { XElement xel = new XElement(new XElement("Root", new XElement("Person", new XElement("Name", "Huang Cong"), new XElement("Sex", "男"), new XElement("Age", 22)), new XElement("Person", new XElement("Name", "Li Si"), new XElement("Sex", "女"), new XElement("Age", 12)) )); //通过LINQ查询将xel的元素添加至新的XElement中 XElement newXel = new XElement(new XElement("NewRoot", new XElement("Persons", xel.Elements().Where(u => u.Name == "Person").Select(u => u) ))); Console.WriteLine(newXel); } }}运行结果:
2.Linq to XML批注LINQ to XML批注是指将一个对象添加或关联到一个XML节点或者属性,批注可以是任何类型的任何对象,可以通过XElement或XAttribute类的AddAnnotation方法来添加批注,需要注意的是:当调用AddAnnotation方法时,是将一个新的对象添加至相应的元素或属性上,原先绑定的批注并不会被删除掉,如果想删除批注,可以调用RemoveAnnotations方法:代码 //-----------------------------------------------------------// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .//-----------------------------------------------------------using System;using System.Xml.Linq;using System.Linq;namespace ConsoleApplication1{ class Program { public class Test { public int Id { get; set; } public string Info { get; set; } } static void Main(string[] args) { XElement xel = new XElement(new XElement("Root", new XElement("Person", "Huang Cong"))); //为元素添加2个批注 xel.Element("Person").AddAnnotation(new Test() { Id = 1, Info = "测试1" }); xel.Element("Person").AddAnnotation(new Test() { Id = 2, Info = "测试2" }); Console.WriteLine("为元素添加2个批注:"); var query = xel.Element("Person").Annotations().Select(u => u); foreach (var q in query) { Console.WriteLine(q.Info); } Console.WriteLine("-------------------------------------"); //删除所有批注 xel.Element("Person").RemoveAnnotations(); Console.WriteLine("删除所有批注:"); query = xel.Element("Person").Annotations().Select(u => u); foreach (var q in query) { Console.WriteLine(q.Info); } Console.WriteLine("-------------------------------------"); } }}运行结果:3.Linq to XML轴LINQ to XML提供了对XML的查询功能,以查找特定的元素或者属性并返回它们的值,LINQ to XML的轴方法让你可以轻松实现以上的功能,LINQ to XML还提供了返回个别节点的方法,这可以让开发人员处理更细粒度的细节.下面是几个主要的轴方法:1. Descendants和DescendantsAndSelf2. Ancestors和AncestorsAndSelf3. ElementsAfterSelf和ElementBeforeSelf下面分别给各个方法做示例讲解:3.1 Descendants和DescendantsAndSelfDescendants方法返回指定元素的后继元素的集合,不包括元素本身,而DescendantsAndSelf则包括元素本身.代码 //-----------------------------------------------------------// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .//-----------------------------------------------------------using System;using System.Xml.Linq;using System.Linq;namespace ConsoleApplication1{ class Program { static void Main(string[] args) { XElement xel = new XElement(new XElement("Root", new XElement("Person", new XElement("Name", "Huang Cong"), new XElement("Age", 22)), new XElement("Person", new XElement("Name", "Li Si"), new XElement("Age", 12)) )); Console.WriteLine("遍历所有元素:"); var des = xel.Descendants(); foreach (var d in des) { Console.WriteLine(d); } Console.WriteLine("----------------------------------"); Console.WriteLine("遍历所有名称为Person的元素,不包括本身:"); des = xel.Descendants("Person").Descendants(); foreach (var d in des) { Console.WriteLine(d); } Console.WriteLine("----------------------------------"); Console.WriteLine("遍历所有名称为Person的元素,包括本身:"); des = xel.Descendants("Person").DescendantsAndSelf(); foreach (var d in des) { Console.WriteLine(d); } Console.WriteLine("----------------------------------"); } }}运行结果:3.2 Ancestors和AncestorsAndSelfAncestors方法返回指定节点的上级元素,不包括元素本身,而AncestorsAndSelf则包括元素本身.代码 //-----------------------------------------------------------// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .//-----------------------------------------------------------using System;using System.Xml.Linq;using System.Linq;namespace ConsoleApplication1{ class Program { static void Main(string[] args) { XElement xel = new XElement(new XElement("Root", new XElement("Person", new XElement("Name", "Huang Cong")) )); Console.WriteLine("遍历所有元素:"); var des = xel.Descendants(); foreach (var d in des) { Console.WriteLine(d); } Console.WriteLine("----------------------------------"); Console.WriteLine("遍历所有名称为Name的元素的上级元素集合,不包括本身:"); des = xel.Element("Person").Element("Name").Ancestors(); foreach (var d in des) { Console.WriteLine(d); } Console.WriteLine("----------------------------------"); Console.WriteLine("遍历所有名称为Name的元素的上级元素集合,包括本身:"); des = xel.Element("Person").Element("Name").AncestorsAndSelf(); foreach (var d in des) { Console.WriteLine(d); } Console.WriteLine("----------------------------------"); } }}运行结果:3.3 ElementsAfterSelf和ElementBeforeSelfElementsAfterSelf方法和ElementBeforeSelf方法分别返回指定元素之后的元素和值指定元素之前的元素,也可以指定条件返回指定的元素集合.代码 //-----------------------------------------------------------// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .//-----------------------------------------------------------using System;using System.Xml.Linq;using System.Linq;namespace ConsoleApplication1{ class Program { static void Main(string[] args) { XElement xel = new XElement(new XElement("Root", new XElement("Person", new XElement("Name", "Huang Cong"), new XElement("Sex","男"), new XElement("Age",12))) ); Console.WriteLine("获取Name元素之后的元素集合:"); var des = xel.Element("Person").Element("Name").ElementsAfterSelf(); foreach (var d in des) { Console.WriteLine(d); } Console.WriteLine("----------------------------------"); Console.WriteLine("获取Name元素之后的名为Sex的元素集合:"); des = xel.Element("Person").Element("Name").ElementsAfterSelf("Sex"); foreach (var d in des) { Console.WriteLine(d); } Console.WriteLine("----------------------------------"); Console.WriteLine("获取Age元素之前的元素集合:"); des = xel.Element("Person").Element("Age").ElementsBeforeSelf(); foreach (var d in des) { Console.WriteLine(d); } Console.WriteLine("----------------------------------"); Console.WriteLine("获取Age元素之前的名为Sex的元素集合:"); des = xel.Element("Person").Element("Age").ElementsBeforeSelf("Sex"); foreach (var d in des) { Console.WriteLine(d); } Console.WriteLine("----------------------------------"); } }}运行结果:4.Linq to XML事件在对XML树进行修改的时候,LINQ to XML事件会提供通知,LINQ to XML提供了2个事件来响应XML树的修改:Changing和Changed.当修改XML树时这2个时间会相继被触发.从运行结果我们可以看出,更新动作实际上是一个删除操作加上一个添加完成的:代码 //-----------------------------------------------------------// All Rights Reserved , Copyright (C) 2010 ,黄聪 , Ltd .//-----------------------------------------------------------using System;using System.Xml.Linq;using System.Linq;namespace ConsoleApplication1{ class Program { static void Main(string[] args) { XElement xel = new XElement(new XElement("Root", new XElement("Person", new XElement("Name", "Huang Cong"), new XElement("Sex","男"), new XElement("Age",12))) ); xel.Changing += new EventHandler(xel_Changing); xel.Changed += new EventHandler(xel_Changed); //修改Person元素的Age元素值 xel.Element("Person").SetElementValue("Age", 22); } static void xel_Changed(object sender, XObjectChangeEventArgs e) { Console.WriteLine("触发Changed事件:"); Console.WriteLine("ChangedValue:{0} \tObjectChange:{1}", ((XNode)sender).ToString(), e.ObjectChange); Console.WriteLine("------------------------------------"); } static void xel_Changing(object sender, XObjectChangeEventArgs e) { Console.WriteLine("触发Changing事件:"); Console.WriteLine("ChangingValue:{0} \tObjectChange:{1}", ((XNode)sender).ToString(), e.ObjectChange); Console.WriteLine("------------------------------------"); } }}运行结果:警告:不允许在被触发事件的执行过程中修改XML树,特别不要在事件中修改触发事件发生的节点,因为这会导致不可预测的结果.不过可以在事件中修改另外一个XML树.小结:LINQ to XML提供了大量方便的方法和接口给开发人员操作XML文档,这大大的提高了开发效率,希望本章的内容对你有所帮助哈,我也是LINQ的初学者,文章中不免会有一些不对的地方,希望高手们多多指点,为我们LINQ初学者们多提宝贵的意见,我也会继续努力的~~
LinqToXML,高级,编程,体验,篇,首先,我们,在,LC#中把DataTable中数据导出Excel编程实例
决定写一片这样的文章,第一给自己也是一种巩固,第二给需要的人也是一种帮助。
(1)首先:添加一个为程序添加一个引用(2)在程序中using一下using Excel = Microsoft.Office.Interop.Excel;using System.Reflection; (3)给你的程序中添加一个模板Excle(一个空的Excle文件就行)这里就起一个名字:temp.xls(4)按照三层架构的思想,以下有2个方法写在中间层。
第一个方法SCexcle()有2个参数,①把你需要导入 Excle的数据集 定义到一个DataTable中,②指向你程序里面前面定义的 temp.xls 模板excel的路径1 Excel.Application app;2 Excel._Workbook wbook;3 Excel._Worksheet oSheet;4 5 public string SCexcel(DataTable dt, string pathLong)6 {7 string wordPath = pathDownLoad + “temp.xls”; //定义模板的路径8 //打开excel文档9 app = new Excel.Application();//添加一个 Excle应用对象10 11 //打开工作簿,可见很多参数,第一个就是我们模板的路径。
12 wbook = app.Workbooks.Open(wordPath, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);13 14 15 oSheet = (Excel._Worksheet)wbook.Worksheets[1];//创建一张sheet表16 17 //定义文件保存路径18 string filename1 = "report" + System.DateTime.Now.Year + System.DateTime.Now.Month + savechinese + ".xls";//因为保存的不平凡,所以之精确到年和月 。
否则就保存到毫秒19 string filename2 = pathLong + "UpLoadFiles\\" + filename1;//保存在服务器的路径20 21 addExecl(filename2.ToString(), dt);//内部的一个方法,把服务器路径与之前的数据放入addExcle()中,目的是在把数据放入Excel中22 23 //打开后就要关闭。
O(∩_∩)O~24 25 app.Workbooks.Close();26 //同样不要忘记结束进程27 System.Runtime.InteropServices.Marshal.ReleaseComObject(oSheet);28 System.Runtime.InteropServices.Marshal.ReleaseComObject(app);29 30 GC.Collect();//强制对所有代进行即时垃圾回收31 32 }第二个方法addExecl();我们来看看他是如何处理数据的,并且使用你自己想要的格式来定义Excel1 private void addExecl(string xlsPath, DataTable dt)2 {3 4 5 Excel.Range oRng;6 Excel.Range range;7 8 9 //标题10 int excel_cur = 1;11 oSheet.Cells[excel_cur, 1] = "大标题";12 excel_cur++;13 14 //字段名 15 oSheet.Cells[excel_cur, 1] = "序号";16 oSheet.Cells[excel_cur, 2] = "字段1";17 oSheet.Cells[excel_cur, 3] = "字段2";18 oSheet.Cells[excel_cur, 4] = "字段3";19 oSheet.Cells[excel_cur, 5] = "字段4";20 oSheet.Cells[excel_cur, 6] = "字段5";21 oSheet.Cells[excel_cur, 7] = "字段6";22 oSheet.Cells[excel_cur, 8] = "字段7";23 oSheet.Cells[excel_cur, 9] = "字段8";24 oSheet.Cells[excel_cur, 10] = "字段9";25 excel_cur++;26 27 //行数据绑定28 if (dt.Rows.Count > 0)29 {30 for (int i = 0; i 效果具体代码添加新工作簿eole.Workbooks.add激活指定的工作簿eole.WorkSheets("工作簿名").Activate设置第3个工作表为激活工作表eole.Worksheets("sheet1").Activate打开指定工作簿 eole.Workbooks.add("E:/E_temp/ABC.xls")更改Excel标题栏eole.Caption="Microsoft Excel"给单元格赋值eole.cells(行,列).value=XM(XM为数据库字段名) eole.cells(1,4).value=‘ASDFASDFASDFASDFADSF‘设置指定列的宽度(单位:字符个数)eole.ActiveSheet.Columns(1).ColumnWidth=5设置指定行的高度(单位:磅)eole.ActiveSheet.Rows(1).RowHeight=1/0.035 //设定行高为1厘米,1磅=0.035厘米在第7行之前插入分页符eole.Worksheets("Sheet1").Rows(7).PageBreak=1在第7列之前删除分页符eole.ActiveSheet.Columns(7).PageBreak=0指定边框线宽度(Borders参数如下)eole.ActiveSheet.Range("b3:d3").Borders(2).Weight=3设置四个边框线条的类型eole.ActiveSheet.Range("b3:d3").Borders(1).Line > (其中Borders参数:1-左、2-右、3-顶、4-底、5-斜、6-斜/;LineStyle值:1与7-细实、2-细虚、4-点虚、9-双细实线)设置页眉eole.ActiveSheet.PageSetup.CenterHeader="报表1"设置页脚eole.ActiveSheet.PageSetup.CenterFooter="第&P页"设置页眉到顶端边距为2厘米eole.ActiveSheet.PageSetup.HeaderMargin=2/0.035设置页脚到底边距为3厘米eole.ActiveSheet.PageSetup.FooterMargin=3/0.035设置顶边距为2厘米eole.ActiveSheet.PageSetup.TopMargin=2/0.035设置底边距为4厘米 eole.ActiveSheet.PageSetup.BottomMargin=4/0.035设置左边距为2厘米eole.ActiveSheet.PageSetup.LeftMargin=2/0.035设置右边距为2厘米eole.ActiveSheet.PageSetup.RightMargin=2/0.035设置页面水平居中eole.ActiveSheet.PageSetup.CenterHorizontally=.t.设置页面垂直居中 eole.ActiveSheet.PageSetup.CenterVertically=.t.设置页面纸张大小(1-窄行8?5?11 39-宽行14?11) eole.ActiveSheet.PageSetup.PaperSize=1可为下列 XlPaperSize 常量之一(某些打印机可能不支持所有的这些纸张大小);常量 数值 意义;xlPaperLetter 1 Letter (8-1/2 in. x 11 in.)xlPaperA3 8 A3 (297 mm x 420 mm)xlPaperA4 9 A4 (210 mm x 297 mm)xlPaperA4Small 10 A4 Small (210 mm x 297 mm)xlPaperA5 11 A5 (148 mm x 210 mm)xlPaperB4 12 B4 (250 mm x 354 mm)xlPaperB5 13 B5 (182 mm x 257 mm)xlPaperFanfoldUS 39 U.S. Standard Fanfold (14-7/8 in. x 11 in.)xlPaperUser 用户自定义打印单元格网线eole.ActiveSheet.PageSetup.PrintGridlines=.t.拷贝整个工作簿eole.ActiveSheet.UsedRange.Copy拷贝指定区域eole.ActiveSheet.Range("A1:E2").Copy粘贴eole.Worksheets("sheet2").Activateeole.ActiveSheet.Range("F1").PasteSpecial在第2行之前插入一行eole.ActiveSheet.Rows(2).Insert在第2列之前插入一列eole.ActiveSheet.Columns(2).Insert设置字体eole.ActiveSheet.Cells(2,1).Font.Name="黑体"设置字体大小eole.ActiveSheet.Cells(1,1).Font.Size=25设置字体为斜体eole.ActiveSheet.Cells(1,1).Font.Italic=.t.设置整列字体为粗体eole.ActiveSheet.Columns(1).Font.Bold=.t.合并单元格eole.ActiveSheet.Range("A1:B4").merge撤销合并单元格,上述操作的逆操作eole.ActiveSheet.Range("A1:B4").unmerge在单元格中设置公式(一般可以用来实现计算汇总、求平均等很多功能)eole.cells(1,4).value = "=公式"** 可以使用所有VBA内部函数,如sum()等。
注意:不能使用VFP的函数啊!清除单元格公式eole.ActiveSheet.Cells(1,4).ClearContents打印预览工作表eole.ActiveSheet.PrintPreview打印输出工作表eole.ActiveSheet.PrintOut工作表另为eole.ActiveWorkbook.SaveAs("c:/temp/22.xls")放弃存盘eole.ActiveWorkbook.saved=.t.关闭工作簿eole.Workbooks.close退出Exceleole.quit以上就是本人对Excel一些微不足道的见解。
写的不周到的地方 也请给位多多担待。
中把,DataTable,中,数据,导出,Excel,编程,
C#编程实现文件压缩生成zip文件
其实用.net自带的类操作起来也非常方便。
以下用一个例子来展示:创建一个文件夹,里面可以包含任意的子目录。
创建一个控制台项目,添加一个类ZipManager,用来实现我们想要的操作。
为项目添加WindowsBase引用。
(这个名字不太友好,但是与压缩相关的类就藏在里面) 在ZipManager.cs中添加对System.IO.Packaging命名空间的引用。
写一个构造函数,用来接收要执行压缩的文件路径。
创建一个方法ZipFolder,用来执行实际的压缩操作。
在这个方法里面创建一个Package的实例。
创建一个函数ZipDirectory,用来递归遍历所有的子目录和子文件夹。
对每一个文件,创建一个PackagePart的实例。
注意这里面相对路径的生成过程:截取比源路径多出的部分,并且将右斜线替换成左斜线。
复制源文件的内容到Package里面,为此需要添加一个CopyStream方法。
ZipManager这个类就大功告成了。
现在我们来调用这个类。
运行一下这个程序,在我们指定的位置,一个zip文件夹生成了。
双击打开,还真是有模有样那。
点评:这个例子只是为了展示.net提供的这一功能。
对于该例子,可以把它扩展的很完善。
以下举一些可以扩展的地方:1. 应用System.IO.Packaging.PackUriHelper类,可以很方便的生成PackagePart的Uri,必须像例子中那样自己生成Uri.2. Package.CreatePart(Uri, String, CompressionOption)方法中的第三个参数,提供压缩方式。
编程,实现,文件,压缩,生成,zip,平时,我们,创建,