Linq初级班 Linq To XML体验(高级编程篇)
首先,我们在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);
}
}
}
// 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 < Test > ().Select(u => u);
foreach (var q in query)
{
Console.WriteLine(q.Info);
}
Console.WriteLine( " ------------------------------------- " );
// 删除所有批注
xel.Element( " Person " ).RemoveAnnotations < Test > ();
Console.WriteLine( " 删除所有批注: " );
query = xel.Element( " Person " ).Annotations < Test > ().Select(u => u);
foreach (var q in query)
{
Console.WriteLine(q.Info);
}
Console.WriteLine( " ------------------------------------- " );
}
}
}
// 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 < Test > ().Select(u => u);
foreach (var q in query)
{
Console.WriteLine(q.Info);
}
Console.WriteLine( " ------------------------------------- " );
// 删除所有批注
xel.Element( " Person " ).RemoveAnnotations < Test > ();
Console.WriteLine( " 删除所有批注: " );
query = xel.Element( " Person " ).Annotations < Test > ().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和DescendantsAndSelf
2. Ancestors和AncestorsAndSelf
3. ElementsAfterSelf和ElementBeforeSelf
下面分别给各个方法做示例讲解:
3.1 Descendants和DescendantsAndSelf
Descendants方法返回指定元素的后继元素的集合,不包括元素本身,而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( " ---------------------------------- " );
}
}
}
// 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和AncestorsAndSelf
Ancestors方法返回指定节点的上级元素,不包括元素本身,而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( " ---------------------------------- " );
}
}
}
// 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和ElementBeforeSelf
ElementsAfterSelf方法和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( " ---------------------------------- " );
}
}
}
// 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 < XObjectChangeEventArgs > (xel_Changing);
xel.Changed += new EventHandler < XObjectChangeEventArgs > (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( " ------------------------------------ " );
}
}
}
// 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 < XObjectChangeEventArgs > (xel_Changing);
xel.Changed += new EventHandler < XObjectChangeEventArgs > (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( " ------------------------------------ " );
}
}
}
运行结果: