LINQToXML
LinqtoXML允许使用Linq查询和处理XML。LinqtoXML并不打算替代标准的XMLAPI,只是补充了这些标准XML类,更便于使用XML。
LinqtoXml为创建和查询xml提供了额外的选项,代码更简单,开发许多常见的情形时速度更快。
4.1LinqtoXML函数构造方法
前面讲到Linq可以方便的构建新的对象,LinqtoXML针对这个主题引入了一个更便捷的方式-------函数构建方式,通过这种方式可以创建XML文档。下面的示例就使用函数构建方式建立了一个包含客户和订单的简单XML文档
staticvoidMain(string[]args) { XDocumentxdoc=newXDocument( newXElement("Customers", newXElement("customer", newXAttribute("ID",1), newXAttribute("City","邯郸"), newXElement("Order",newXAttribute("Item","大饼"), newXAttribute("price",2) ), newXElement("Order",newXAttribute("Item","馒头"), newXAttribute("price",1)) ), newXElement("customer", newXAttribute("ID",2), newXAttribute("City","武安"), newXElement("Order",newXAttribute("Item","烧饼"), newXAttribute("price",2) ), newXElement("Order",newXAttribute("Item","油条"), newXAttribute("price",1)) )) ); Console.WriteLine(xdoc); } |
![](http://hi.csdn.net/attachment/201110/12/0_1318420826OmW6.gif)
说明:
1.需要引入命名空间:System.Xml.Linq
2.XDocument():在LinqtoXml构造函数中层次结构最高,表示一个完整的XML文档。
3.XElement():XML文档的节点。
4.XAttribute():XML节点的属性。
5.除此之外,LinqtoXML还提供了其他构造函数:
XDeclaration()用于XML文档开头的XML声明,
XComment()用于XML文档的注释。
6.以上构造函数可以相互嵌套使用
7.Console.WriteLine(xdoc)调用了XDoucument()的默认方法ToString()方法。
8.用字符串构建XML元素文本
本示例中格式化了XML,其元素中没有文本内容。如果想为XML节点增加文本内容只需把字符串传入构造函数即可,如:
XDocumentxdoc=newXDocument( newXElement("Customers", newXElement("customer","邯郸", newXAttribute("ID",1)) )); |
输出结果为:
4.2保存和加载XML文档
注意,用Console.WriteLine()把XML文档输出到屏幕上时,不会显示<?xmlversion=”1.0”开头的XML声明。但可以使用XDeclaration()构造函数显示创建声明,但一般不需要这么做,因为在调用Save()方法保存XML文档时会自动创建声明。
stringfileName=@"d:\example.xml"; xdoc.Save(fileName);//保存xml文档 XDocumentxdoc2=XDocument.Load(fileName);//从文件加载 Console.WriteLine(xdoc2); |
保存XML文档的默认编码方式是UTF-8,如果想改变此编码可以使用XDeclaration()对象,或设置XDocument的Declaration属性:
xdoc.Declaration=newXDeclaration("1.0","gb2312","yes");
4.3从字符串中加载XML
XDocumentxdoc=XDocument.Parse(@" <Customers> <customerID=""1"">邯郸</customer> </Customers>"); |
此示例中注意双引号的写法。
4.4处理XML片段
LinqtoXml处理Xml片段(部分)的方式和处理完整的Xml文档完全相同,只要把Xelement当做顶级Xml对象即可。
XElementxcust= newXElement("Customers", newXElement("customer","邯郸", newXAttribute("ID",1)) ); stringfileName=@"d:\example2.xml"; xcust.Save(fileName); XDocumentxcust2=XDocument.Load(fileName); Console.WriteLine(xcust2); |
说明:
Xelemet和Xdocument继承自LinqtoXml类XContainer,它实现了一个可以包含其他Xml节点的XML节点,这个类都实现了Load()和Save()方法,因此可以在Xdocument上执行的大多数操作都可以在XElement上执行。
4.5通过LinqtoXml生成XML
Xml常常用于在客户机和服务器之间传递数据,或者在多层应用程序的不同层之间传递数据。在数据库中查询某些数据,再根据这些数据生成Xml文档,传送给另一层是很常见的。对上一章的示例做如下修改:
MyStuDataContextmydc=newMyStuDataContext(); XElementstu=newXElement("students", fromsinmydc.student selectnewXElement("student", newXElement("name",s.name), newXElement("age",s.age), newXElement("sex",s.sex))); stringpath=@"d:\example4.xml"; stu.Save(path); Console.WriteLine(stu); |
注意:select语句的投射并没有生成一个新的对象,而是嵌套的元素节点。
必须使用XElement对象,不能使用XDocument对象。
4.6查询XML文档
对Xml文档的查询使我们程序中经常遇到的情况,LinqtoXml类提供了成员属性和方法,它们返回Xml文档或片段中可以查询的、由该LinqtoXml类表示的LinqtoXml对象集合。下面的代码在上一示例的基础上进行查询。
stringpath=@"d:\example4.xml"; XDocumentxdoc=XDocument.Load(path); varresult=fromsinxdoc.Elements() selects.Name; foreach(variteminresult) { Console.WriteLine(item); } |
1.Elements():返回Xml文档或片段中所有第一级元素。对于有效的Xml文档,只返回根元素。
2.Descendants():返回Xml文档或片段中的所有子元素(所有级别的子元素)。示例如下:
stringpath=@"d:\example4.xml"; XDocumentxdoc=XDocument.Load(path); varresult=fromsinxdoc.Descendants() selects.Name; foreach(variteminresult) { Console.WriteLine(item); } |
查看所有元素并不是常常需要在程序中使用的,Descendants()方法有一个重载,传入一个元素名作为字符串参数,用于查找指定名称的子元素。
stringpath=@"d:\example4.xml"; XDocumentxdoc=XDocument.Load(path); varresult=fromsinxdoc.Descendants("student") selects; foreach(variteminresult) { Console.WriteLine(item); } |
这是一个比较有用的查询,得到一组元素后,就可以搜索特定的属性:
stringpath=@"d:\example4.xml"; XDocumentxdoc=XDocument.Load(path); varresult=fromsinxdoc.Descendants("student").Attributes() selects; foreach(variteminresult) { Console.WriteLine(item); } |
3.Attribute()方法返回当前选中元素的所有属性。同Descendants()方法一样,也可以给Attribute()方法传送一个具体的名称,另外,不仅可以显示名称,还可以显示属性本身。
可以用Value属性获取属性的值。
stringpath=@"d:\example3.xml"; XDocumentxdoc=XDocument.Load(path); varresult=fromsinxdoc.Descendants("student").Attributes("name") selects.Value; foreach(variteminresult) { Console.WriteLine(item); } |
以上示例如果配合where子句将更加精确的查找出需要的元素及元素相关属性和值
4.7Xml文档的更新
4.7.1添加
stringpath=@"d:\example3.xml"; XDocumentxdoc=XDocument.Load(path); varresult=fromsinxdoc.Descendants("student") wheres.Attribute("age").Value=="20" selects; foreach(variteminresult) { item.Add(newXElement("class","50")); //item.AddAfterSelf(newXElement("name",new //XAttribute("age",20),newXAttribute("sex","女"))); //item.AddBeforeSelf(newXElement("No","S100")); } xdoc.Save(path); |
Add()方法可以给节点添加一个子节点(XElement)或者一个属性(XAttribute)
AddAfterSelf()在节点之后添加
AddBeforeSelf()在节点之前添加
这两个方法仅限于节点,不能应用于属性。
再次调用Save()方法将添加后的文档保存。
4.7.2更新节点
//更新XML节点 XElementStudents=newXElement("Students", newXElement("Student", newXElement("Name","张三"), newXElement("Sex","男"), newXElement("Age",newXAttribute("Year",1989/8/22),20)) ); Students.Element("Student").Element("Age").ReplaceWith(newXElement("Age",28));//替换掉整个节点 //Students.Element(“Student”).Element(“Age”).ReplaceNodes(28); //只替换节点值 //Students.Element(“Student”).Element(“Age”).ReplaceAll(28); //替换掉整个节点 Console.WriteLine(Students); |
4.7.3删除节点
//删除XML节点 XElementStudents=newXElement("Students", newXElement("Student", newXElement("Name","张三"), newXElement("Sex","男"), newXElement("Age",newXAttribute("Year","1989/8/22"),20)) ); //Students.Element("Student").Element("Age").Remove();//移除节点 //Students.Element("Student").Element("Age").RemoveAll();//移除节点的值和属性 Students.Element("Student").Element("Age").RemoveNodes();//移除节点的值 Console.WriteLine(Students); |
4.7.4添加属性
//添加XML属性 XElementStudents=newXElement("Students", newXElement("Student", newXElement("Name","张三"), newXElement("Sex","男"), newXElement("Age",newXAttribute("Year","1989/8/22"),20)) ); Students.Element("Student").SetAttributeValue("dd","dddd"); Console.WriteLine(Students); |
4.7.5更新属性
//更新XML属性 Students.Element("Student").Element("Age").ReplaceAttributes(newXAttribute("Year","dd")); Students.Element("Student").Element("Age").SetAttributeValue("Year","dddd"); |
4.7.6删除属性
//删除XML属性 Students.Element("Student").Element("Age").Attribute("Year").Remove(); Students.Element("Student").Element("Age").RemoveAttributes(); |
4.8Xml文档的遍历
4.8.1遍历节点
XElementStudents=newXElement("Students", newXElement("Student", newXElement("Name","张三"), newXElement("Sex","男"), newXElement("Age",20)), newXElement("Student", newXElement("Name","李四"), newXElement("Sex","女"), newXElement("Age",19)) ); foreach(XNodenodeinStudents.Nodes()) { Console.WriteLine(node); Console.WriteLine("----------------------------"); } foreach(XElementeleinStudents.Elements()) { Console.WriteLine(ele); Console.WriteLine("********************************"); } |
4.8.2遍历属性
//遍历XML属性 varAttr=fromattinStudents.Element("Student").Element("Age").Attributes() selectatt; foreach(varattinAttr) { Console.WriteLine(att); } |