LINQ to XML LINQ学习第一篇

1、LINQ to XML类

以下的代码演示了如何使用LINQ to XML来快速创建一个xml:

  1. public static void CreateDocument()
  2. {
  3. string path = @"d:\website";
  4. XDocument xdoc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"),
  5. new XElement("Root", "root"));
  6. xdoc.Save(path);
  7. }

运行该示例将会得到一个xml文件,其内容为:

  1. <?xml version="1.0" encoding="utf-8" standalone="yes"?>
  1. <Root>root</Root>

2、XElement类

XElement 类是 LINQ to XML 中的基础类之一。 它表示一个 XML 元素。 可以使用该类创建元素;更改元素内容;添加、更改或删除子元素;向元素中添加属性;或以文本格式序列化元素内容。 还可以与 System.Xml 中的其他类(例如 XmlReader、XmlWriter 和 XslCompiledTransform)进行互操作。

使用LINQ to XML创建xml文档有很多种方式,具体使用哪种方法要根据实际需要。而创建xml文档最简单、最常见的方式是使用XElement类。以下的代码演示了如何使用XElement类创建一个xml文档:

  1. public static void CreateCategories()
  2. {
  3. string path = @"d:\website";
  4. XElement root = new XElement("Categories",
  5. new XElement("Category",
  6. new XElement("CategoryID", Guid.NewGuid()),
  7. new XElement("CategoryName", "Beverages")
  8. ),
  9. new XElement("Category",
  10. new XElement("CategoryID", Guid.NewGuid()),
  11. new XElement("CategoryName", "Condiments")
  12. ),
  13. new XElement("Category",
  14. new XElement("CategoryID", Guid.NewGuid()),
  15. new XElement("CategoryName", "Confections")
  16. )
  17. );
  18. root.Save(path);
  19. }

运行该示例将会得到一个xml文件,其内容为:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Categories>
  3. <Category>
  4. <CategoryID>57485174-46fc-4e8c-8d98-d25b53d504a1</CategoryID>
  5. <CategoryName>Beverages</CategoryName>
  6. </Category>
  7. <Category>
  8. <CategoryID>1474dde1-8014-48f7-b093-b47ca5d5b770</CategoryID>
  9. <CategoryName>Condiments</CategoryName>
  10. </Category>
  11. <Category>
  12. <CategoryID>364224e0-e002-4939-90fc-0fd93e0cf35b</CategoryID>
  13. <CategoryName>Confections</CategoryName>
  14. </Category>
  15. </Categories>
  1.  

XElement类包含了许多方法,这些方法使得处理xml变得轻而易举。有关这些方法请参照MSDN。

其中,Save、CreateReader、ToString和WriteTo方法是比较常用的三个方法:

3、XAttribute类

XAttribute类用来处理元素的属性,属性是与元素相关联的“名称-值”对,每个元素中不能有名称重复的属性。使用XAttribute类与使用XElement类的操作十分相似,下面的示例演示了如何在创建xml树时为其添加一个属性:

  1. public static XElement CreateCategoriesByXAttribute()
  2. {
  3. XElement root = new XElement("Categories",
  4. new XElement("Category",
  5. new XAttribute("CategoryID", Guid.NewGuid()),
  6. new XElement("CategoryName", "Beverages")
  7. ),
  8. new XElement("Category",
  9. new XAttribute("CategoryID", Guid.NewGuid()),
  10. new XElement("CategoryName", "Condiments")
  11. ),
  12. new XElement("Category",
  13. new XAttribute("CategoryID", Guid.NewGuid()),
  14. new XElement("CategoryName", "Confections")
  15. )
  16. );
  17. root.Save(path);
  18. return root;
  19. }

运行该示例将会得到一个xml文件,其内容为:

  1.  
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Categories>
  3. <Category CategoryID="a6d5ef04-3f83-4e00-aeaf-52444add7570">
  4. <CategoryName>Beverages</CategoryName>
  5. </Category>
  6. <Category CategoryID="67a168d5-6b22-4d82-9bd4-67bec88c2ccb">
  7. <CategoryName>Condiments</CategoryName>
  8. </Category>
  9. <Category CategoryID="17398f4e-5ef1-48da-8a72-1c54371b8e76">
  10. <CategoryName>Confections</CategoryName>
  11. </Category>
  12. </Categories>

XAttribute类的方法比较少,常用的三个是:

以下的示例使用Remove来删除第一个元素的CategoryID属性:

  1. public static void RemoveAttribute()
  2. {
  3. XElement xdoc = CreateCategoriesByXAttribute();
  4. XAttribute xattr = xdoc.Element("Category").Attribute("CategoryID");
  5. xattr.Remove();
  6. xdoc.Save(path);
  7. }

运行该示例将会得到一个xml文件,其内容为:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Categories>
  3. <Category>
  4. <CategoryName>Beverages</CategoryName>
  5. </Category>
  6. <Category CategoryID="5c311c1e-ede5-41e5-93f7-5d8b1d7a0346">
  7. <CategoryName>Condiments</CategoryName>
  8. </Category>
  9. <Category CategoryID="bfde8db5-df84-4415-b297-cd04d8db9712">
  10. <CategoryName>Confections</CategoryName>
  11. </Category>
  12. </Categories>

作为尝试,试一试以下删除属性的方法:

  1. public static void RemoveAttributeByDoc()
  2. {
  3. XElement xdoc = CreateCategoriesByXAttribute();
  4. XAttribute xattr = xdoc.Attribute("CategoryID");
  5. xattr.Remove();
  6. xdoc.Save(path);
  7. }

运行该示例将会抛出一个空引用异常,因为元素Categories没有一个叫做CategoryID的属性。

4、XDocument类

XDocument类提供了处理xml文档的方法,包括声明、注释和处理指令。一个XDocument对象可以包含以下内容:

下面的示例创建了一个简单的xml文档,它包含几个元素和一个属性,以及一个处理指令和一些注释:

  1. public static void CreateXDocument()
  2. {
  3. XDocument xdoc = new XDocument(
  4. new XProcessingInstruction("xml-stylesheet", "title='EmpInfo'"),
  5. new XComment("some comments"),
  6. new XElement("Root",
  7. new XElement("Employees",
  8. new XElement("Employee",
  9. new XAttribute("id", "1"),
  10. new XElement("Name", "Scott Klein"),
  11. new XElement("Title", "Geek"),
  12. new XElement("HireDate", "02/05/2007"),
  13. new XElement("Gender", "M")
  14. )
  15. )
  16. ),
  17. new XComment("more comments")
  18. );
  19. xdoc.Save(path);

运行该示例将会得到一个xml文件,其内容为:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <?xml-stylesheet title='EmpInfo'?>
  3. <!--some comments-->
  4. <Root>
  5. <Employees>
  6. <Employee id="1">
  7. <Name>Scott Klein</Name>
  8. <Title>Geek</Title>
  9. <HireDate>02/05/2007</HireDate>
  10. <Gender>M</Gender>
  11. </Employee>
  12. </Employees>
  13. </Root>
  14. <!--more comments-->

XDocument类包含多个与XElement类相同的方法,具体内容可以参阅MSDN。需要注意的是,处理节点和元素的大部分功能都可以通过XElement获得,只有当绝对需要文档层次的处理能力,以及需要访问注释、处理指令和声明时,才有使用XDocument类的必要。

创建了xml文档后,可以使用NodesAfterSelf方法返回指定的XElement元素之后的所有同级元素。需要注意的是,此方法只包括返回集合中的同级元素,而不包括子代。此方法使用延迟执行。以下代码演示了这一过程:

  1. public static void NodesAfterSelf()
  2. {
  3. XElement root = new XElement("Categories",
  4. new XElement("Category",
  5. new XElement("CategoryID", Guid.NewGuid()),
  6. new XElement("CategoryName", "食品"),
  7. new XElement("Description", "可以吃的东西")
  8. )
  9. );
  10. foreach (var item in root.Element("Category").Element("CategoryID").NodesAfterSelf())
  11. {
  12. Console.WriteLine((item as XElement).Value);
  13. }
  14. }

二、LINQ to XML编程概念

本节将介绍LINQ to XML编程的相关概念,例如如何加载xml、创建全新xml、操纵xml的信息以及遍历xml文档。

1、加载已有的xml

使用LINQ to XML加载xml可以从多种数据源获得,例如字符串、XmlReader、TextReader或文件。

下面的示例演示了如何从文件中加载xml:

  1. public static void LoadFromFile()
  2. {
  3. XElement root = XElement.Load(path);
  4. Console.WriteLine(root.ToString());
  5. }

也可以使用Parse方法从一个字符串加载xml:

  1. public static void LoadFromString()
  2. {
  3. XElement root = XElement.Parse(@"
  4. <Categories>
  5. <Category>
  6. <CategoryID>1</CategoryID>
  7. <CategoryName>Beverages</CategoryName>
  8. <Description>Soft drinks, coffees, teas, beers, and ales</Description>
  9. </Category>
  10. </Categories>
  11. ");
  12. Console.WriteLine(root.ToString());
  13. }

2、保存xml

在前面的示例中曾多次调用XElement对象的Save方法来保存xml文档,在这里就不冗述了。

3、创建xml

在前面的示例中曾多次调用XElement对象的构造函数来创建xml文档,在这里就不冗述了。需要说明的是,在使用LINQ to XML创建xml文档时,会有代码缩进,这使代码的可读性大大加强。

4、遍历xml

使用LINQ to XML在xml树中遍历xml是相当简单的。只需要使用XElement和XAttribute类中所提供的方法。Elements和Element方法提供了定位到某个或某些元素的方式。下面的示例演示了如何遍历xml树,并获取指定元素的方式:

  1. public static void Enum()
  2. {
  3. XElement root = new XElement("Categories");
  4. using (NorthwindDataContext db = new NorthwindDataContext())
  5. {
  6. root.Add(
  7. db.Categories
  8. .Select
  9. (
  10. c => new XElement
  11. (
  12. "Category"
  13. , new XElement("CategoryName", c.CategoryName)
  14. )
  15. )
  16. );
  17. }
  18. foreach (var item in root.Elements("Category"))
  19. {
  20. Console.WriteLine(item.Element("CategoryName").Value);
  21. }
  22. }

上述代码运行的结果为:

是不是很简单呢?Nodes()、Elements()、Element(name)和Elements(name)方法为xml树的导航提供了基本功能。

5、操纵xml

LINQ to XML一个重要的特性是能够方便地修改xml树,如添加、删除、更新和复制xml文档的内容。

I.插入

使用XNode类的插入方法可以方便地向xml树添加内容:

在下面的示例中,使用AddAfterSelf方法向现有xml中添加一个新节点:

  1. public static void AddAfterSelf()
  2. {
  3. XElement root = XElement.Parse(@"
  4. <Categories>
  5. <Category>
  6. <CategoryID>1</CategoryID>
  7. <CategoryName>Beverages</CategoryName>
  8. <Description>Soft drinks, coffees, teas, beers, and ales</Description>
  9. </Category>
  10. </Categories>
  11. ");
  12. XElement xele = root.Element("Category").Element("CategoryName");
  13. xele.AddAfterSelf(new XElement("AddDate", DateTime.Now));
  14. root.Save(path);
  15. }

运行该示例将会得到一个xml文件,其内容为:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Categories>
  3. <Category>
  4. <CategoryID>1</CategoryID>
  5. <CategoryName>Beverages</CategoryName>
  6. <AddDate>2010-01-31T03:08:51.813736+08:00</AddDate>
  7. <Description>Soft drinks, coffees, teas, beers, and ales</Description>
  8. </Category>
  9. </Categories>

当需要添加一个元素到指定节点之前时,可以使用AddBeforeSelf方法。

II.更新

在LINQ to XML中更新xml内容可以使用以下几种方法:

在下面的示例中使用了ReplaceWith与SetElementValue方法对xml进行了更新操作:

  1. public static void Update()
  2. {
  3. XElement root = XElement.Parse(@"
  4. <Categories>
  5. <Category>
  6. <CategoryID>1</CategoryID>
  7. <CategoryName>Beverages</CategoryName>
  8. <Description>Soft drinks, coffees, teas, beers, and ales</Description>
  9. </Category>
  10. </Categories>
  11. ");
  12. root.Element("Category").Element("CategoryID").ReplaceWith(new XElement("ID", "2"));
  13. root.Element("Category").SetElementValue("CategoryName", "test data");
  14. root.Save(path);
  15. }

运行该示例将会得到一个xml文件,其内容为:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Categories>
  3. <Category>
  4. <ID>2</ID>
  5. <CategoryName>test data</CategoryName>
  6. <Description>Soft drinks, coffees, teas, beers, and ales</Description>
  7. </Category>
  8. </Categories>

III.删除

可以使用Remove(XElement)与RemoveAll方法来删除xml。

在下面的示例中,使用了RemoveAll方法:

  1. public static void Remove()
  2. {
  3. string path = @"d:\";
  4. XElement root = XElement.Parse(@"
  5. <Categories>
  6. <Category>
  7. <CategoryID>1</CategoryID>
  8. <CategoryName>Beverages</CategoryName>
  9. <Description>Soft drinks, coffees, teas, beers, and ales</Description>
  10. </Category>
  11. </Categories>
  12. ");
  13. root.RemoveAll();
  14. root.Save(path);
  15. }

运行该示例将会得到一个xml文件,其内容为:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Categories />

在下面的示例中,使用了Remove方法删除了xml的Description元素:

  1. public static void Remove()
  2. {
  3. XElement root = XElement.Parse(@"
  4. <Categories>
  5. <Category>
  6. <CategoryID>1</CategoryID>
  7. <CategoryName>Beverages</CategoryName>
  8. <Description>Soft drinks, coffees, teas, beers, and ales</Description>
  9. </Category>
  10. </Categories>
  11. ");
  12. root.Element("Category").Element("Description").Remove();
  13. root.Save(path);
  14. }

运行该示例将会得到一个xml文件,其内容为:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Categories>
  3. <Category>
  4. <CategoryID>1</CategoryID>
  5. <CategoryName>Beverages</CategoryName>
  6. </Category>
  7. </Categories>

6、处理属性

I.添加

LINQ to XML添加属性与添加元素师类似的,可以使用构造函数或者Add方法来添加属性:

  1. public static void AddAttribute()
  2. {
  3. XElement root = new XElement("Categories",
  4. new XElement("Category",
  5. new XAttribute("CategoryID", "1"),
  6. new XElement("CategoryName", "Beverages"),
  7. new XElement("Description", "Soft drinks, coffees, teas, beers, and ales")
  8. )
  9. );
  10. root.Element("Category").Add(new XAttribute("AddDate", DateTime.Now.ToShortDateString()));
  11. root.Save(path);
  12. }

运行该示例将会得到一个xml文件,其内容为:

  1. <?xml version="1.0" encoding="utf-8"?>
  1.  
  1. <Categories>
  1.  
  1. <Category CategoryID="1" AddDate="2010-01-31">
  1.  
  1. <CategoryName>Beverages</CategoryName>
  1.  
  1. <Description>Soft drinks, coffees, teas, beers, and ales</Description>
  1.  
  1. </Category>
  1.  
  1. </Categories>
  1.  

II.检索

检索属性可以使用Attribute(name)方法:

  1. public static void SelectAttribute()
  2. {
  3. XElement root = new XElement("Categories",
  4. new XElement("Category",
  5. new XAttribute("CategoryID", "1"),
  6. new XElement("CategoryName", "Beverages"),
  7. new XElement("Description", "Soft drinks, coffees, teas, beers, and ales")
  8. )
  9. );
  10. XAttribute xattr = root.Element("Category").Attribute("CategoryID");
  11. Console.WriteLine(xattr.Name);
  12. Console.WriteLine(xattr.Value);
  13. }

上述代码的运行结果为:

CategoryID

1

本文总结

本文介绍了LINQ to XML的编程基础,即System.Xml.Linq命名空间中的多个LINQ to XML类,这些类都是LINQ to XML的支持类,它们使得处理xml比使用其他的xml工具容易得多。在本文中,着重介绍的是XElement、XAttribute和XDocument。

收藏
关注
评论
 
分类: Linq

LINQ to XML LINQ学习第一篇的更多相关文章

  1. 从.Net到Java学习第一篇——开篇

    以前我常说,公司用什么技术我就学什么.可是对于java,我曾经一度以为“学java是不可能的,这辈子不可能学java的.”结果,一遇到公司转java,我就不得不跑路了,于是乎,回头一看N家公司交过社保 ...

  2. Java并发包下锁学习第一篇:介绍及学习安排

    Java并发包下锁学习第一篇:介绍及学习安排 在Java并发编程中,实现锁的方式有两种,分别是:可以使用同步锁(synchronized关键字的锁),还有lock接口下的锁.从今天起,凯哥将带领大家一 ...

  3. JVM学习第一篇思考:一个Java代码是怎么运行起来的-上篇

    JVM学习第一篇思考:一个Java代码是怎么运行起来的-上篇 作为一个使用Java语言开发的程序员,我们都知道,要想运行Java程序至少需要安装JRE(安装JDK也没问题).我们也知道我们Java程序 ...

  4. Android基础学习第一篇—Project目录结构

    写在前面的话: 1. 最近在自学Android,也是边看书边写一些Demo,由于知识点越来越多,脑子越来越记不清楚,所以打算写成读书笔记,供以后查看,也算是把自己学到所理解的东西写出来,献丑,如有不对 ...

  5. Golang学习-第一篇 Golang的简单介绍及Windows环境下安装、部署

    序言 这是本人博客园第一篇文章,写的不到位之处,希望各位看客们谅解. 本人一直从事.NET的开发工作,最近在学习Golang,所以想着之前学习的过程中都没怎么好好的将学习过程记录下来.深感惋惜! 现在 ...

  6. Python学习第一篇

    好久没有来博客园了,今天开始写自己学习Python和Hadoop的学习笔记吧.今天写第一篇,Python学习,其他的环境部署都不说了,可以参考其他的博客. 今天根据MachineLearning里面的 ...

  7. ImageJ 学习第一篇

    ImageJ是世界上最快的纯Java的图像处理程序.它可以过滤一个2048x2048的图像在0.1秒内(*).这是每秒40万像素!ImageJ的扩展通过使用内置的文本编辑器和Java编译器的Image ...

  8. Java图像处理最快技术:ImageJ 学习第一篇

    ImageJ是世界上最快的纯Java的图像处理程序. 它能够过滤一个2048x2048的图像在0.1秒内(*). 这是每秒40万像素!ImageJ的扩展通过使用内置的文本编辑器和Java编译器的Ima ...

  9. Linq专题之提高编码效率—— 第一篇 Aggregate方法

    我们知道linq是一个很古老的东西,大家也知道,自从用了linq,我们的foreach少了很多,但有一个现实就是我们在实际应用中使用到的却是屈指可数 的几个方法,这个系列我会带领大家看遍linq,好的 ...

随机推荐

  1. SVN提交忽略*.class、.classpath、.mymetadata、.project、.settings、.myeclipse和其他非版本控制文件

    1.忽略*.class 在TortoiseSVN -->setting(设定)--规设置 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveHVrZTY ...

  2. c# socket 判断端口是否被占用

    using System.Net; using System.Net.Sockets; using System.Net.NetworkInformation; IPGlobalProperties ...

  3. asp.net mvc3 数据验证(四)—Remote验证的一个注意事项

    原文:asp.net mvc3 数据验证(四)-Remote验证的一个注意事项         前几篇把asp.net mvc3 中基于Model的主要数据验证的方法都已经讲完了,本节纯粹只是讲一个我 ...

  4. C语言库函数大全及应用实例十四

    原文:C语言库函数大全及应用实例十四                                       [编程资料]C语言库函数大全及应用实例十四 函数名: strset 功 能: 将一个串 ...

  5. JavaScript重载解读

    在JavaScript有一个特殊的数据类型---Function种类,JavaScript每个功能Function的类型,例如可以.由于函数是对象.指针,不会与某个函数绑定. <pre name ...

  6. angular.js的一点理解

    对angular.js的一点理解 2015-01-14 13:18 by MrGeorgeZhao, 317 阅读, 4 评论, 收藏, 编辑 最近一直在学习angular.js.不得不说和jquer ...

  7. 记录一下Fedora21下安装Foundation5遇到的问题[尚有遗留问题]

    写在前面:之前安装过了gem,所以下面的步骤没有这一过程,再有就是忘记哪一步需要ruby中的一个.h文件.可以使用如下命令解决 sudo yum install ruby-devel ------ S ...

  8. Spring之SpringMVC前端控制器DispatcherServlet(源码)分析

    1.DispatcherServlet作用说明 DispatcherServlet提供Spring Web MVC的集中访问点,而且负责职责的分派,而且与Spring IoC容器无缝集成,从而可以获得 ...

  9. openwrt驱动与应用程序的联系

    应用程序与驱动之间需要进行命令的传递,因而它们之间需要共同定义一套双方都可以识别的数据结构,实际使用时它们include的是名字和内容相同但位置不同的头文件. 比如spi_gpio_ad7193.h这 ...

  10. [译]JDK 6 and JDK 7中的subString()方法

    (说明,该文章翻译自The substring() Method in JDK 6 and JDK 7) 在JDK 6 and JDK 7中的substring(int beginIndex, int ...