对LINQ TO SQL的内容讲解将告一段落,下面我们进入LINQ学习之旅的最后一站"LTX",即LINQ TO XML。当前XML技术在应用开发中显得越来越重要,已成为各类数据交换的标准。那么相对地就需要有关于XML数据的操作接口来处理这些XML数据,比如XML DOM、XSLT、XPath和XQuery等技术,但这些技术和C#语言不是一种概念模型,且使用方法也比较复杂。所以LINQ TO XML就提供了一个轻量级的XML编程接口,它允许像操作内存对象那样操作XML数据。相对于上述提到的一些旧的XML编程接口,LINQ TO XML使开发人员更容易上手。下面分别用XML DOM编程接口和LINQ TO XML编程接口来创建一个相同的XML文档,通过这两个示例的对比来说明LINQ TO XML的优势。
下面用XML DOM编程接口创建XML文档:
1 staticvoid Main(string[] args)
2 {
3 //创建XML文档
4 XmlDocument xdc =new XmlDocument();
5
6 //创建根元素
7 XmlElement sprites = xdc.CreateElement("Sprites");
8
9 //第一个精灵
10 XmlElement sprite1 = xdc.CreateElement("Sprite01");
11
12 //职业
13 XmlElement profession1 = xdc.CreateElement("Profession");
14 profession1.InnerText ="法师";
15
16 //武器
17 XmlElement weapon1 = xdc.CreateElement("Weapon");
18 weapon1.InnerText ="魔杖";
19
20 //添加上述节点
21 sprites.AppendChild(sprite1);
22 sprite1.AppendChild(profession1);
23 sprite1.AppendChild(weapon1);
24
25 //同理
26
27 //第二个精灵
28 XmlElement sprite2 = xdc.CreateElement("Sprite02");
29
30 //职业
31 XmlElement profession2 = xdc.CreateElement("Profession");
32 profession2.InnerText ="战士";
33
34 //武器
35 XmlElement weapon2 = xdc.CreateElement("Weapon");
36 weapon2.InnerText ="屠龙刀";
37
38 //添加上述节点
39 sprites.AppendChild(sprite2);
40 sprite2.AppendChild(profession2);
41 sprite2.AppendChild(weapon2);
42
43 //第三个精灵
44 XmlElement sprite3 = xdc.CreateElement("Sprite03");
45
46 //职业
47 XmlElement profession3 = xdc.CreateElement("Profession");
48 profession3.InnerText ="道士";
49
50 //武器
51 XmlElement weapon3 = xdc.CreateElement("Weapon");
52 weapon3.InnerText ="倚天剑";
53
54 //添加上述节点
55 sprites.AppendChild(sprite3);
56 sprite3.AppendChild(profession3);
57 sprite3.AppendChild(weapon3);
58
59 //根节点添加到xml文档
60 xdc.AppendChild(sprites);
61
62 xdc.Save(@"d:\\Sprites.xml");
63
64 }
结果:
从上述示例代码中可以看到,用XML DOM编程接口创建XML文档必须严格遵守强制语法,首先创建元素节点,再将元素节点添加到相应位置。这样对于比较小的XML文档来说还可以,但如果XML文档内容量很大,那么首先在创建XML代码中很难看出其数据层级结构,其次在创建XML文档过程中会大量使用临时变量,使得代码可读性降低,且维护起来也困难。现在用LINQ TO XML来创建一个XML文档:
1 staticvoid Main(string[] args)
2 {
3 //LINQ TO XML编程接口创建XML文档
4 XElement Sprites =new XElement(
5 "Sprites",
6 new XElement("Sprite01",
7 new XElement("Profession", "法师"),
8 new XElement("Weapon", "魔杖")),
9 new XElement("Sprite02",
10 new XElement("Profession", "战士"),
11 new XElement("Weapon", "屠龙刀")),
12 new XElement("Sprite03",
13 new XElement("Profession", "道师"),
14 new XElement("Weapon", "倚天剑")));
15
16 Sprites.Save(@"d:\\Sprites.xml");
17 }
结果:相同(略);
从LINQ TO XML创建的XML文档的语法来看,首先就显得非常简洁,再者从编码中就可以很清楚地看出结果XML文档的层次结构。LINQ TO XML允创建XML数据文件采用函数式的编程思想,在一条语句里就可以创建一个XML数据文件,不需要像XML DOM那样使用大量的临时变量。最后还有一点,LINQ TO XML在创建XML文档时,不需要先创建文档对象。而XML DOM就必须先要创建XML文档对象,即使在具体的操作过程中不需要建立XML文档,XML文档对象也要被创建。其实LINQ TO XML中的创建的元素都被存于内存当中,而无需依附XML文档对象,尽管LINQ TO XML中也提供了类XDocument,来完成XML文档的相关操作。
讲明了LINQ TO XML编程接口相对于XML DOM的优势,接下来具体谈谈LINQ TO XML的编程接口。LINQ TO XML的编程接口包含以下关系图中的这些类:
下面对图中的类进行一一说明:
1.XObject类
XObject类是LINQ TO XML编程接口中其他类的基类,其中内部定义了几个常用方法。其中AddAnnotation方法用于向XObject对象添加注释,而RemoveAnnotation方法用于删除注释内容。Annotation和方法Annotations用获取XObject对象的注释或注释集合,且注释不限于字符串,可以是任何类型对象。下面通过示例说明(因为XObject是虚基类,所以不能实例化对象):
i.为继承XObject类的类对象添加注释:
1 //创建xml元素
2 XElement Sprites =new XElement("Sprites","Sprite01");
3
4 //添加注释
5 Sprites.AddAnnotation("精灵集合");
6
7 //取出注释
8 string str_note = Sprites.Annotation<string>();
9
10 Console.WriteLine("注释内容:{0}",str_note);
11 Console.WriteLine(Sprites.ToString());
12
13 //删除注释
14 Sprites.RemoveAnnotations<string>();
15
16 Console.Read();
ii.结果:
2.XNode类
XNode类代表XML的节点,其中有常用方法AddAfterSelf、AddBeforeSelf、Ancestors、NodesAfterSelf、NodesBeforeSelf和Remove,这些都是对XML节点的操作方法。这些方法的详细介绍将在之后几节里说明,在这里就点到为止。
3.XAttribute类
XAttribute类是关联到XML节点元素的名称—值类型对象,代表XML的属性。常用属性的属性有Parent用于获取其所属父节点对象,Name属性用于获取属性的名称,Value则获取或设置对应属性的值,Remove用于将自身从父节点中删除。下面通过示例说明:
i.XAttribute类属性和方法使用:
1 XAttribute xa;
2 XElement Sprite01 =new XElement("Sprite01",
3 new XAttribute("Profession","法师"),
4 xa=new XAttribute("Weapon","魔杖")
5 );
6
7 Console.WriteLine("XML数据修改前:\n{0}", Sprite01.ToString());
8
9 Console.WriteLine("属性{0}的父节点:\n{1}",xa.ToString(),xa.Parent.ToString());
10
11 Console.WriteLine("XML数据修改后:");
12 //删除属性
13 xa.Remove();
14 //修改指定属性值
15 Sprite01.Attribute("Profession").Value="魔法师";
16
17 Console.WriteLine(Sprite01);
18
19 Console.Read();
ii.结果:
4.XContainer类
XContainer类是一个抽象类,目的在于向节点提供包含节点的能力,其中有常用方法Add、AddFirst、RemoveNodes以及RepalceNode(替换自身节点所包含的所有子节点),同样的因为XContainer类是抽象类,所以不能生成对象。
5.XComment类
XComment类用于在XML中提供注释内容,它与之前XObject类中提到的注释Annotation是不一样的,XComment类的注释可以在XML文档中看到,其属性Value就是用来设置注释内容。下面通过示例说明:
i.给XML文档添加注释:
1 XElement sprites =new XElement(
2 "Sprites",
3 new XComment("注释:下面是所有精灵的介绍"),//创建注释
4 new XElement("Sprite01",
5 new XElement("Profession", "法师"),
6 new XElement("Weapon", "魔杖")),
7 new XElement("Sprite02",
8 new XElement("Profession", "战士"),
9 new XElement("Weapon", "屠龙刀")),
10 new XElement("Sprite03",
11 new XElement("Profession", "道师"),
12 new XElement("Weapon", "倚天剑")));
13
14 Console.WriteLine(sprites);
15
16 Console.Read();
ii.结果:
6.XDocumentType类、XProcessingInstruction类、XText类和XCData类
XDocumentType类代表XML文档类型,XML文档类型是XML文档符合有效性的一个基本要求;XProcessingInstruction类代表XML处理指令,用于通知XML处理程序如何处理数据;XText类代表一个文本节点;而XText类的派生类XCData用于创建XML CData值。
7.XElement类和XDocument类
这两个类派生于虚基类XContainer,所以XContainer类有的方法,在类XElement和XDocument也可以使用。XElement类代表XML元素节点,它可以包含其他节点,也可以包含上面刚提到过的节点属性XAttribute。同时它也提供了大量的方法用于操作XML元素节点方法,比如Attributes方法、AncestorsAndSelf方法、DescendantsAndSelf方法等,还有XElement类常用的静态方法Load(从外界读取数据)、静态方法Parse(从字符串生成XML数据)、以及Save方法(把XML数据保存到存储设备)。XDocument类和XElement类非常相似,也有静态方法Load、静态方法Parse以及Save方法。但两者不同之处在于XDocument类可以包含一些和文档相关的信息,比如XML文档类型、文档声明等;
8.XDeclaration类、XName类和XNamespace类
XDeclaration类代表XML声明,定义XML版本、编码等信息;XName类代表XML元素的名称或XML属性的名称;XNamespace类代表XML命名空间。