LINQ to SQL
LINQ to SQL提供了一种把关系型数据库映射到编程语言表示的对象模型,使用得开发人员可以通过编程语言直接操作数据库,数据库的访问由此变得更加快捷和高效。
- 对象模型的原理
与LINQ to DataSet一样它也是ADO.NET和LINQ结合的产物。它把编程对象和数据库关系模型直接映射,比LINQ to DataSet更进一步。
在LINQ to SQL中,开发人员不用向数据库发出SQL命令,而是在对象模型中直接更改值或执行方法。当开发人员通过对象模型执行操作时,LINQ to SQL把请求转换成SQL命令,然后把这些命令发送到数据库,得到返回数据库服务器的操作结果后,再把这些结果传递给到对象模型。
由于对象模型和关系型数据库中每个元素之间有一种一对一的映射关系,开发人员才可以通过对象模型来访问数据库。
数据库表DataTable,被映射成为C#类
数据库表的列(字段),被映射到C#类的成员(属性)
数据库表的外键关系(Relation)被映射成为C#类的关联
数报库表中的存储过程被或函数被映射成到C#类的方法
创建对象模型的常用3种方法:
1.对象关系设计器:O/R设计器
2.SQLMetal代码生成工具,它的可操作性差,无界面
3.代码编辑器,这个方法编码工作量大,容易出错
- O/R设计器
在Visual Studio2017中没有LINQ to SQL模板的话,则可以使用“工具”-“获取工具和功能”-“单个组件”中添加LINQ to SQL即可。
在“数据源”中,可以添加当前项目需要绑定的数据源
在界面中添加DataGridView,并绑定对应的数据
LINQ to XML
- XML
extensible Markup Language,可扩展标记语言,广泛用于网络、数据传输和存储、数据库等领域。
LINQ to XML提供了一套通过LINQ在内存中操作XML数据的编程接口,相当于更新和重新设计的文档对象模型XML编程接口。 - LINQ to XML概述
LINQ to XML提供使用LINQ在内存中操作XML数据的编程接口,它提供比DOM更简洁的开发接口。还可以通过LINQ直接对内存中的XML数据进行查询或更改,代码更加简洁和高效。 - 关于LINQ to XML
XML和HTML一样,是一种标识语言。和HTML相比,XML具有可扩展性、面向对象等特性。
在.NET Framework中,开发人员或以通过System.Xml命名空间提供的相关类库完成XML数据的读写。还有一个System.Xml.Linq命名空间,这个命名空间提供了一套新的读写XML数据的编程接口——LINQ to XML。
把XML文档置于内存中,在查询、修改xml文档后可以把它另存为文件,也可以把它序列化然后通过网络发送。
LINQ to XML最重要的优势在于它与LINQ的集成,可以对内存XML文档编写查询,从而检索元素和属性的集合。
通过把查询结果用作XElement和XAttribute对象构造函数的参数,实现了一种功能强大的创建XML树的方法。这种方法称为“函数构造”。利用这种方法,开发人员可以方便把XML树从一种形态转为另一种形态。
LINQ to XML主要类:
1.Extensions:提供了所有LINQ to XML类的扩展方法
2.XAttriute:这个类表示一个XML节点的属性
3.XCData:这个类表示一个包含CDATA的文本节点
4.XComment:这个类表示一个XML文件的注释
5.XContainer:表示XML文件中可以包含其它节点的结节
6.XElement:这个类从XContainer类派生,表示一个XML元素
7.XDocument:这个类从XContainer类派生,表示的是一个完整的XML文档
8.XDocumentType:这个类表示XML文档的类型定义DTD
9.XDeclaration:这个表示一个XML文件的XML声明,通常出现在XML文件头部
10.XName:这个类表示XML文件中元素或属性的名称
11.XText:这个类表示一个文本节点
12.XNamespace:这个类表示XML命名空间
13.XNode:这个类表示XML树中节点的抽象概念
14.XNodeDocumentOrderComparer:这个类表示比较结点的文档顺序的功能
15.XNodeEqualityComparer:这个类用来比较节点确定是否相等
16.XObject:这个类用来表示XML树中节点或属性
17.XObjectChangeEventArgs:这个类提供有关XObject类属性Changing和Changed事件的数据
18.XProcessingInstruction:这个类用来表示一个XML的处理指令
19.XStreamingElement:这个类表示支持延迟流输出的XML树中的元素
20.LoadOptions:这个枚举类型指定分析XML时的加载选项,包含None、PreserveWhitespace、SetBaseUri和SetLineInfo4个或选值
21.SaveOptions:这个枚举指定序列化选项,包含None、DisableFormatting两个可选值
22.XObjectChange:这个枚举指定为XObject引发事件时的事件类型,包含Add、Remove、Name和Value这4个可选值
注意:在使用类和枚举的时候要先引用System.Xml和System.Xml.Linq命名空间。
- DOM 与 LINQ to XML
命名空间System.Xml提供了对DOM的支持。
使用DOM与LINQ来生成XML的方法如下: - DOM生成
//创建XmlDocument表示XML
XmlDocument doc = new XmlDocument();
//创建根节点BookList
XmlElement bookList = doc.CreateElement("BookList");
XmlElement book, auth;
//创建子节点Book-1
book = doc.CreateElement("Book");
book.SetAttribute("Name", "Book-1");
auth = doc.CreateElement("Author");
auth.InnerText = "Author-1";
book.AppendChild(auth);
bookList.AppendChild(book);
//创建子节点Book-2
book = doc.CreateElement("Book");
book.SetAttribute("Name", "Book-2");
auth = doc.CreateElement("Author");
auth.InnerText = "Author-2";
book.AppendChild(auth);
bookList.AppendChild(book);
//把根节点添加到文档
doc.AppendChild(bookList);
/*FileStream f = null;
try
{
f = File.Create(@"D:\book1.xml");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
f.Close();
}*/
//这个方法会自动创建对应的文档
doc.Save(@"D:\book1.xml");
生成的xml文件如下:
- LINQ生成
XElement bookLst =
new XElement("BookList", //根节点 BookList
new XElement[]
{
new XElement("Book",//第 1 个节点 Book-1
new object[]{ //属性 Name 和子元素 Author
new XAttribute("Name", "Book-1"),
new XElement("Author", "Author-1")}),
new XElement("Book", //第 2 个节点 Book-2
new object[]{ //属性 Name 和子元素 Author
new XAttribute("Name", "Book-2"),
new XElement("Author", "Author-2")}),
}
);
bookLst.Save(@"D:\book2.xml");
比较项 | DOM | LINQ |
---|---|---|
直接使用xml元素 | 必须在xml文档上下文中创建xml节点,包括节点的元素和属性 | 可以直接使用xml元素和属性,可不通过XML文档对象创建xml元素,把xml元素序列化到文件流 |
构造新的XML树或节点 | 代码量大可读性不好 | 代码简单,xml结构清晰,可读性好 |
跨文档使用xml元素 | 需要加载多个xml文档,在各自的上下文中使用xml元素 | 不需要加载多个xml文档,直接使用xml元素,除非在文档根级别添加xml元素 |
修改节点名称 | 只有在创建时确定,创建完后不可以修改 | 可以通过XName类修改任意xml节点或属性的名称 |
对片段的支持 | 提供XmlDocumentFragment类支持xml片段 | 通过XNode转化IEnumerable进行查询实现 |
- 构造XML树
构造xml文档是最基本的xml文档操作之一,在进行xml文档数据操作之前,都需要先在内存中创建XML树,然后才对其进行操作。
1.构造简单的XML元素
在LINQ to XML中使用XElement类表示XML文档中的元素,XElement类提供多个不同版本的构造函数。
1.public XElement(XName name)
2.public XElement(XElement element)
3.public XElement(XName name,object content)
参数name表示包含元素名称的XName对象。
参数element表示新Xml元素的源元素,这个函数创建一个源元素的深层副本。
参数content是object类型,表示元素的内容,所以空强以是任何的数据类型,而显示的内容则是这个对象的ToString()方法所返回的字符串。
XName类并没有提供构造函数,所以不可以创建XName类型对象作为参数传入XElement构造函数,但是是存在一个从字符串到XName类型的隐式转换,所以只需要把一个string类型参数传入到XElement构造函数即可。
XElement类的ToString()方法返回元素的文本形式,包括制表符和空白。
如下实例,新建一个自定义类并把使用XElement构造函数生成对应的XML元素
//创建一个UserClass类
public class UserClass
{
private string name;
private int age;
public UserClass(int age, string name)
{
this.age = age;
this.name = name;
}
//重写ToString()方法
public override string ToString()
{
return string.Format("{0}的年龄是:{1}", name, age);
}
}
static void CreateElement()
{
//创建简单的XML元素,使用XElement(XName)的使用
XElement ele1 = new XElement("User");
Console.WriteLine("ele1:\n"+ele1);
//创建简单的XML元素,使用XElement(XElement),做深层的副本
XElement ele2 = new XElement(ele1);
Console.WriteLine("ele2:\n" + ele2);
//创建一个带内容的XML元素,使用XElement(XName,object)
XElement ele3 = new XElement("name", "名称");
Console.WriteLine("ele3:\n" + ele3);
//创建元素内容类型为float的XML元素,使用XElement(XName,object)
XElement ele4 = new XElement("PI", 3.1415f);
Console.WriteLine("ele4:\n" + ele4);
//创建元素内容类型为DateTime的XML元素,使用XElement(XName,object)
XElement ele5 = new XElement("DateTime", DateTime.Now);
Console.WriteLine("ele5:\n" + ele5);
//创建元素内容类型为匿名类类型的XML元素,使用XElement(XName,object)
XElement ele6 = new XElement("AnoymousClass", new { x = 1.01, y = 2.01, z = 3.33 });
Console.WriteLine("ele6:\n" + ele6);
//创建元素内容类型为自定义类类型的XML元素,使用XElement(XName,object)
UserClass uc = new UserClass(20, "谢声");
XElement ele7 = new XElement(uc.GetType().Name,uc);
Console.WriteLine("ele7:\n" + ele7);
}
在Main方法中做如下调用:
CreateElement();
Console.ReadKey();
编译运行结果如下:
2.构造具有属性的xml元素
在LINQ to XML中,使用XAttribute类表示一个XML元素的属性。它包括一个(名称,值)数据对,用来表示这个属性的名称和值。任何xml元素都包含一个XAttribute列表,用来表示它所包含的所有属性。同一个XML元素所包含的属性名是不可以重复的。
XAttribute类构造函数可以创建XML属性
1.public XAttribute(XName name,object value)
2.public XAttribute(XAttribute other)
参数 name 表示属性(Attribute)的名称,其是XName类型,同样只需使用字符串参数即可。参数value表示属性的值,它是object类型,所以属性的值可以是任何类型。
第二个版本用来创建一个已有属性的深层副本,参数other表示要被复制的属性对象。
在LINQ to XML中,用XElement类构造函数创建XML元素,结合XAttribute类可以创建带有属性的XML元素。
XElement类提供了一个具有可变参数的构造函数,用来创建各种复杂样式的XML元素
public XElement(XNmae name,params object[] content)
name:它是一个XName对象,表示元素的名称
content:它是一个可变参数,为object类型,可以传入任何类型的参数
当要创建具有属性的XML元素,就需要使用上面的XElement构造函数,传入的content为XAttribute类对象时,则表示这个元素的一个属性,但是不能在同一个XElement对象中创建两个以上具有同名称的XAttribute类的对象。
创建一个类并创建一个生成属性的方法
//创建一个Userclass类
public class UserClass
{
private string Name;
private int Age;
public UserClass(string name, int age)
{
Name = name;
Age = age;
}
//重写ToString()
public override string ToString()
{
return string.Format("{0}的年龄是:{1}", Name, Age);
}
}
//XML属性创建
static void CreateXmlAttributeEle()
{
//创建类型为string的属性,使用XAttribute(XName,object)方法
XAttribute attr1 = new XAttribute("Name", "xiesheng");
Console.WriteLine("attr1:"+attr1);
//创建属性的深层的副本,使用XAttribute(XAttribute)
XAttribute attr2 = new XAttribute(attr1);
Console.WriteLine("attr2:" + attr2);
//创建类型为DateTime的属性,使用XAttribute(XName,object)
XAttribute attr3 = new XAttribute("DateTime", DateTime.Now);
Console.WriteLine("attr3:" + attr3);
//创建自定义类的属性,使用XAttribute(XName,object)
XAttribute attr4 = new XAttribute("UserClass",new UserClass("谢声", 30));
Console.WriteLine("attr4:" + attr4);
//创建一个Xml元素,传入XAttribute参数,使用XElement(XName,object[])
XElement ele1 = new XElement("Student", attr1);
Console.WriteLine("ele1:\n" + ele1);
//传入一个XAttribute数组
XAttribute[] attrArray = { attr3, attr4 };
XElement ele2 = new XElement("Student_time", attrArray);
Console.WriteLine("ele2:\n" + ele2);
}
在Main方法中做如下调用测试
CreateXmlAttributeEle();
Console.ReadKey();
编译运行的结果如下:
3.构造有子元素的XML元素
一个xml元素,一般是包含一个或多个子元素,可以通过XElement的可变参数版本构造函数创建具有子元素的xml元素。当传入的参数是XElement类型的时候,这个参数则是所有xml元素的子元素。注意:xml元素的子元素的排列顺序与它们作为参数传入的顺序相同,当传入的是数组时,数组中元素可以看成从0-n的顺序展开的多个参数来看待。
新增一个创建带子元素的XML元素的方法
//创建带有子元素的xml元素
static void CreateSubElement()
{
//直接在构造函数中创建XML文档
XElement userList1 = new XElement("UserList",
new XElement("User",
new XElement("Name","张三"),
new XElement("Age",30)
),
new XElement("User",
new XElement("Name", "李四"),
new XElement("Age", 20)
)
);
//先创建两个用户的xml元素
XElement user1 = new XElement("User",
new XElement("Name","张三"),
new XElement("Age",30));
XElement user2 = new XElement("User",
new XElement("Name", "李四"),
new XElement("Age", 20));
//创建带两个用户信息的xml元素
XElement userList2 = new XElement("UserList", user1, user2);
//使用两个用户信息数组来创建xml元素
XElement[] xes = { user1, user2 };
XElement userList3 = new XElement("UserList", xes);
//输出结果
Console.WriteLine("userList1:\n" + userList1);
Console.WriteLine();
Console.WriteLine("userList2:\n" + userList2);
Console.WriteLine();
Console.WriteLine("userList3:\n" + userList3);
}
在Main方法中调用这个方法进行测试
CreateSubElement();
Console.ReadKey();
编译运行结果如下:
4.使用XElement类构造XML树
在XML元素中,通常包含元素、属性、内容等多个特性,可以使用XElement类的可变参数的构造函数同时传入类型为XAttribute和XElement则可以,在传入多个参数中,如果参数是XAttribute则这个参数就是XML元素的属性,如果参数为XElement类型时,这个参数就是xml元素的子元素,如果传入的是int,string,float等类型时,这些参数的字符串形式按照先后顺序连接起来作为元素的内容。
新增一个创建XML树的方法
//创建XML树
static void CreateXMLTree()
{
//创建用户1
XElement user1 = new XElement("User",
new XAttribute("Name", "张三"),
new XAttribute("Age", 30));
//创建用户2
XElement user2 = new XElement("User",
new XAttribute("Name", "李四"),
new XAttribute("Age", 20));
//创建一个具有多个用户列表的XML元素
XElement userList = new XElement("UserList", "string content",
user1, user2, new XAttribute("Count", 2), 100);
Console.WriteLine("UserList:\n" + userList);
}
在Main方法中做如下调用测试
CreateXMLTree();
Console.ReadKey();
编译运行结果如下:
- 查询XML树
XElement类通过Elements和Attributes提供当前XML元素的子元素和属性集合,通过这两个集合则可以对XML文档中的元素进行查询操作。
1.查找具有特定属性的元素
用来获取XML元素中的属性和子元素的方法:
a.Element():获取当前xml元素的第一个具有指定名称的子元素
b.Elements():获取当前xml元素的所有子元素,或具有指定名称的所有子元素,返回的类型为IEnumerable元素集合
c.Attribute():获取当前xml元素具有指定名称的属性
d.Attributes():获取当前xml元素的所有属性,或具有指定名称的属性,返回类型为IEnumerable属性集合
创建一个UserList.xml的xml文档
新建一个创建xml文档的方法:
//创建xml文档
static void CreateXMLByLINQ()
{
XElement userList =
new XElement("UserList",
//节点Count
new XElement("Count",4),
//创建第一个节点User
new XElement("User",new XAttribute("Name","张三"),
new XAttribute("Age","23"),
new XElement("Sex","Male"),
new XElement("Mobile","13012345678")),
//创建第二个节点User
new XElement("User", new XAttribute("Name", "李四"),
new XAttribute("Age", "20"),
new XElement("Sex", "Male"),
new XElement("Mobile", "130223456789")),
//创建第三个节点User
new XElement("User", new XAttribute("Name", "李敏"),
new XAttribute("Age", "18"),
new XElement("Sex", "Female"),
new XElement("Mobile", "13323445678")),
//创建第四个节点User
new XElement("User", new XAttribute("Name", "王霞"),
new XAttribute("Age", "22"),
new XElement("Sex", "Female"),
new XElement("Mobile", "13613344678"))
);
userList.Save(@"D:\UserList.xml");
}
在Main方法中调用创建xml文档的方法
CreateXMLByLINQ();
Console.WriteLine("xml文档创建完成");
Console.ReadKey();
编译运行结果如下:
生成xml文档如下:
<?xml version="1.0" encoding="utf-8"?>
<UserList>
<Count>4</Count>
<User Name="张三" Age="23">
<Sex>Male</Sex>
<Mobile>13012345678</Mobile>
</User>
<User Name="李四" Age="20">
<Sex>Male</Sex>
<Mobile>130223456789</Mobile>
</User>
<User Name="李敏" Age="18">
<Sex>Female</Sex>
<Mobile>13323445678</Mobile>
</User>
<User Name="王霞" Age="22">
<Sex>Female</Sex>
<Mobile>13613344678</Mobile>
</User>
</UserList>
要对xml文档进行查询处理需要做如下工作:
1.使用XElement类中的Load()方法把文档加载到内存
2.使用Elements(),Attributes(),Element(),Attribute()方法查找所有或指定元素或属性
程序中添加一个查询元素和属性的方法如下 :
//查询xml文档中元素或属性
static void QueryAttributeElement()
{
//从文件中加载xml数据到内存中
XElement root = XElement.Load(@"D:\UserList.xml");
IEnumerable<XElement> Users = root.Elements("User");
//查询所有的User
var userList =
from ele in Users select ele;
foreach (var item in userList)
{
Console.WriteLine(item);
}
//查询所有User的姓名
var nameList =
from ele in Users select ele.Attribute("Name");
foreach (string name in nameList)
{
Console.Write("{0},",name);
}
Console.WriteLine();
//查询所有年龄大于等于20岁的User
var ageList =
from ele in Users
where int.Parse(ele.Attribute("Age").Value) >= 20
select new { Name = ele.Attribute("Name"), Age = ele.Attribute("Age") };
foreach (var item in ageList)
{
Console.WriteLine(item);
}
}
在Main方法中做如下调用
QueryAttributeElement();
Console.ReadKey();
编译运行结查如下:
2.查找具有特定子元素的元素
在LINQ to XML中,可以通过XElement类的Elements()方法进行子元素的名称过滤,通过Element()方法进行指子元素的获取。
Elements()返回的元素是IElements类型,可以用where子句对它的元素进行条件判断,从而实现元素的过滤,即查找到满足指这下条件的子元素。
在程序中添加如下方法进行子元素的查询
//查找指定子元素
static void QuerySubElement()
{
//从文件中加载xml文档到内存中
XElement root = XElement.Load(@"D:\UserList.xml");
IEnumerable<XElement> users = root.Elements("User");
var query1 =
from ele in users
from ele2 in ele.Elements()
where "Sex".Equals(ele2.Name.LocalName)
select new { name = ele.Attribute("Name").Value, sex = ele2.Value };
//输出查询结果
foreach (var item in query1)
{
Console.WriteLine(item);
}
//查询性别为Female的用户
var query2 =
from ele in users
where "Female".Equals(ele.Element("Sex").Value)
select ele;
Console.WriteLine("性别为Female的用户:");
foreach (var item in query2)
{
Console.WriteLine(item);
}
}
在Main方法中做如下调用
QuerySubElement();
Console.ReadKey();
编译运行的结果如下:
3.对xml元素进行排序
对xml元素的查询结果进行排序使用orderby子句完成,只是排序的原则是通过XElement类Attribute()和Element()等方法获得的XML元素数据。
在程序中新增排序方法如下:
//对xml元素进行排序
static void OrderByElement()
{
//加载xml文档到内存
XElement root = XElement.Load(@"D:\UserList.xml");
IEnumerable<XElement> users = root.Elements("User");
var query1 =
from ele in users
orderby ele.Attribute("Age").Value descending //按年龄从大到小排序
select new { name = ele.Attribute("Name").Value, age = ele.Attribute("Age") };
Console.WriteLine("按年龄从大到小排序:");
foreach (var item in query1)
{
Console.WriteLine(item);
}
//对年龄大于等于20的用户,按年龄从大到小排序
var query2 =
from ele in users
where int.Parse(ele.Attribute("Age").Value)>=20
orderby ele.Attribute("Age").Value descending
select new { name = ele.Attribute("Name").Value, age = ele.Attribute("Age") };
Console.WriteLine("年龄大于等于20岁的用户按年龄从大到小排序:");
foreach (var item in query2)
{
Console.WriteLine(item);
}
}
在Main方法中做如下调用:
OrderByElement();
Console.ReadKey();
编译运行结果如下:
4.基于上下文查询元素
在一些应用中,需要根据元素上下状态进行查询。LINQ to XML类提供了以下两个方法来获取元素前后的兄弟元素
1.ElementsAfterSelf():获取符合指定名称,并按文档顺序和当前元素后面的同级元素的集合,返回类型为IEnumerable
2.ElementsBeforeSelf():获取符合指定名称,并按文档顺序和当前元素前面的统计元素集合,返回类型为:IEnumerable
在程序中添加如下方法进行上下查询
//基于上下文进行查询
static void QueryInContext()
{
XElement root = XElement.Load(@"D:\UserList.xml");
IEnumerable<XElement> users = root.Elements("User");
//所有后续元素结点数量大于2的元素
var query1 =
from ele in users
where ele.ElementsAfterSelf("User").Count() > 2
select ele;
Console.WriteLine("查询结果:");
foreach (var item in query1)
{
Console.WriteLine(item);
}
//所有前续元素结点数量大于2的元素
var query2 =
from ele in users
where ele.ElementsBeforeSelf("User").Count() > 2
select ele;
Console.WriteLine("查询结果:");
foreach (var item in query2)
{
Console.WriteLine(item);
}
}
在Main方法中添加如下代码进行调用测试
QueryInContext();
Console.ReadKey();
编译运行结果如下:
- 操作XML树
1.加载和保存xml树
加载xml树到内存中的方法
Load方法
public static XElement Load(string uri);
public static XElement Load(TextReader textReader);
public static XElement Load(XmlReader reader);
public static XElement Load(string uri,LoadOptions options);
public static XElement Load(TextReader textReader,LoadOptions options);
public static XElement Load(XmlReader reader,LoadOptions options);
参数说明:
uri:string类型,表示要包含xml数据的文件路径,这个路径可以是相对路径或绝对路径。
textReader,reader:表示包含xml数据的文本数据流或xml数据流
options:LoadOptions枚举类型,用来指定空白行为及是否加载基URI和行信息
LoadOptions枚举可选值:
None:不保留无关紧要的空白,也不加载基URI和行信息
PreserveWhiteSpace:分析时保留无关紧要的空白
SetBaseUri:从XmlReader请求基URI信息,并通过BaseUri属性使此信息可用
SetLineInfo:从XmlReader请求行信息并通过XObject上的属性使此信息可用
在程序中新增一个方法加载xml文件并读取行信息
//操作xml树
static void LoadXMLTree()
{
//创建段简单的xml数据
string xmlData =
@"<ItemList>
<Item1 />
<Item3 />
<ITem5 />
</ItemList>";
//把xml数据写入到临进文件中
File.WriteAllText("tempData.xml", xmlData);
//使用Load方法来加载xml临时文件中的内容,同时加载行和空白信息
XElement ele = XElement.Load("tempData.xml", LoadOptions.SetLineInfo);
//在Item1和Item3分别添加Item2,Item4两个新的子元素
ele.Element("Item1").AddAfterSelf(new XElement("Item2"));
ele.Element("Item3").AddAfterSelf(new XElement("Item4"));
//打印ele中所有元素,DescendantsAndSelf()这个方法是返回元素的集合
foreach (XElement item in ele.DescendantsAndSelf())
{
//把XElement强制转为IXmlLineInfo类,从而可以获取包含行号信息
if (((IXmlLineInfo)item).HasLineInfo())
Console.Write("Line {0} :\t", ((IXmlLineInfo)item).LineNumber);
else
Console.Write("Line XX:\t");
Console.Write(item.Name);
Console.WriteLine();
}
}
在Main方法中调用这个方法:
LoadXMLTree();
Console.ReadKey();
编译运行的结果如下:
temList、Item1、Item3 和 Item5 都是从文件读取,并且包含行信息,但是 Item2 和 Item4 则在加载之后新增,并不包含特定的行信息。并且我们可以看到新增记录后,原有行信息仍是保持不变的。
2.向xml树中添加元素
XElement类继承自己XNode类和XContainer类,它们为XElement类提供了几种添加元素、属性等节点的方法
a.Add():这个方法由XContainer类实现,在当前节点子节点的末尾添加内容
public void Add(Object content)
public void Add(params Object[] content)
b.AddFirst():这个方法由XContainer类实现,在当前节点的第一个子节点之前添加内容
public void AddFirst(Object content)
public void AddFirst(params Object[] content)
c.AddAfterSelf():这个方法由XNode类实现,在当前节点后面添加内容
public void AddAfterSelf(Object content)
public void AddAfterSelf(params Object[] content)
d.AddBeforeSelf():这个方法由XNode类实现,在当前节点前面添加内容
public void AddBeforeSelf(Object content)
public void AddBeforeSelf(params Obejct[] content)
从上面的定义可以看到,可以同时添加一个或多个xml元素,因而可以把LINQ查询产生的IEnumerable类型的查询结果直接通过上面的方法添加到XElement中,也可以把自己行创建的XElement数组或单个XElement对象添加到XElement中
3.移除xml树中元素和属性
XElement类本身提供的方法可以移除它的元素和属性
RemoveAll()
RemoveAttributes()
这两个方法不接受任何参数,也不返回任何值
RemoveAll():移除XElement中所有的元素和属性
RemoveAttributes():移除XElement中所有的属性
当只需要移除XElement元素的一个或多个属性和子元素而并非全部时,可以使用另外的两个方法
SetAttributeValue()和SetElementValue()
SetAttributeValue():用于设置XElement元素中指定属性的值,当设置的值为null时,表示删除这个属性
SetElementValue()用于设置XElement元素中指定子元素的值,当设置为null时,表示删除这个子元素
这两个函数的具体定义如下:
public void SetAttributeValue(XName name,Object value)
public void SetElementValue(XName name,Object value)
name:表示要设置的属性或子元素的名称
value:表示要设置的新值
在程序中添加删除元素和属性的方法:
//xml元素和属性删除
static void RemoveElementAttribute()
{
//原始数据的构建
XElement ele = new XElement("Student");
ele.SetAttributeValue("Name", "李四");
ele.SetAttributeValue("Class", "181班");
ele.SetAttributeValue("Age", 20);
ele.SetElementValue("数学", 90);
ele.SetElementValue("语文",80);
ele.SetElementValue("英文", 70);
ele.SetElementValue("综合", 85);
Console.WriteLine("原始数据:");
Console.WriteLine(ele);
//返回成绩大于80分的元素
IEnumerable<XElement> eleList =
from e in ele.Elements()
where int.Parse(e.Value) > 80
select e;
//移除查询出的结果
eleList.Remove();
Console.WriteLine("移除成绩大于80的元素后:");
Console.WriteLine(ele);
//获取名称为"英文"的子元素,并做移除
XElement eleEnglish = ele.Element("英文");
eleEnglish.Remove();
Console.WriteLine("再移除英文成绩后:");
Console.WriteLine(ele);
//获取名称为Age和Class的属性,并移除属性
IEnumerable<XAttribute> atrList =
from a in ele.Attributes()
where (a.Name == "Class") || (a.Name == "Age")
select a;
atrList.Remove();
Console.WriteLine("再移除Age和Class属性后:");
Console.WriteLine(ele);
}
在Main方法中对这个方法做调用测试
RemoveElementAttribute();
Console.ReadKey();
编译运行结果如下: