现在的位置: 首页 > 综合 > 正文

用Linq to XML的方式查询XML 文档

2011年01月31日 ⁄ 综合 ⁄ 共 2828字 ⁄ 字号 评论关闭

Linq to XML的方式查询XML 文档

August 6, 2007 15:20 by Block4

语言级集成查询(LinQ)是一种新的通过Dot net 查询数据的统一的方法。现在已经有大量的关于LinQ的强大功能的讨论了,并且假如你已经有测试它的性能的机会的话,你一定认可上面的这些讨论的。假如用一些很简短的话证明Linq是一个一流的,有效地数据存取的方法的话,我想说 几乎任何数据结构(数组,关系数据,集合,)都可以通过LinQ变成数据源

 

虽然dot net包含一个管理XML的库(System.XML,LinQ to XML扩展了这个命名空间,带来了标准的查询操作并将这些操作和XML文档组合在一起(System.XML.Linq)。我们可以将XML文档加载到内存中,通过用LinQ语句来查询它。对于一个已经习惯于SQL查询的开发者来讲,Linq语句似乎是一个XXX语言。但是这样的语句逻辑更清晰,查询实现更自然。

 

现在让我们开始讨论应用了Linq to XML 的一些基础的例子,简单的XML文档将从这儿被找到,它是被微软用于一些关于XML操作的简单例子中的,但被稍微修改版的文档,为了测试这些操作,我已经用Visual Studio 2008 Beta 2 建立一个新的控制台应用程序(这是最快显示结果的方式) 。所以你必须妥善的将这些包含XML测试文件包含到简单的项目中。

 

我们可以通过XDocument 类的Load方法将XML文档加载到内存中,我选择这种方法加载的原因是我的第一个例子包含了一个根元素<catalog>,否则你想直接面向于文档中的某一特定元素,你可以用XElementLoad方法, 于是说,我们想呈现所有包含在<Catalog>中的主要元素,于是所有的<Book>元素

XDocument xmlFile = XDocument.Load("books.xml");

var query = from c in xmlFile.Elements("catalog").Elements("book")

select c;

foreach (XElement book in query)

{

Console.WriteLine(book.Value.ToString());

}

输出将由<book>类型的节点包含的信息构成,不显示任何子标签,换句话说 假如在我们向控制台写得时候,排出 Value属性 结果将包含所有的<book>节点和他们的子节点结构,正像我们在XML文档中看到的一样。

 

下一步 将如我们想要找出当前有效的书,为了实现,我们需要更准确的查找一些属性的值,更准确的说

<book>元素的Checked-out  属性。

var query = from c in xmlFile.Elements("book")

where (string)c.Attribute("checked-out").Value == "false"            

select c;

foreach (var book in query)

{

Console.WriteLine("\”{0}\” is available", book.Element("title").Value);

}

我们可以用Descendants方法在嵌套元素中导航,对这个方法补充说明的是  假如在特殊的节点中包含了一些你可能在查询中用到的属性,用Attributes方法 并且 在这种情况下 注意查询对象的成员是XAttribute 类型。下面是我们怎么找出有多少本书在它的描述中包含“.net”关键字

var query = from c in xmlFile.Descendants("description")

where c.Value.Contains(".NET")

select c;

Console.WriteLine("We found {0} book(s) on .NET", query.Count());

我们可以走出更远的一步,去试着找出每一个作者写的所有书的全部价值,下面是代码段,我将解释什么语法元素将被用到:

var query = from c in xmlConfigFile.Descendants("book")

group new

{             

Author = (string)c.Element("author"), BookValue = (double)c.Element("value")      

}      

by (string)c.Element("author")      

into groupedData

select new

{

AuthorName = groupedData.Key, BooksTotalValue = groupedData.Sum(rec => rec.BookValue)

}; 

foreach (var v in query)

{

Console.WriteLine("Author: {0}; Value of all this author's books: {1}", v.AuthorName, v.BooksTotalValue);

}

首先,我们将选择所有在XML文档中的<book>元素的信息,将如你愿意的话 这些信息将被一个新的对象或者是记录分组(有许多语法元素在这里关系到Linq to object),并且我们将保留bookauthor属性和Value 属性 (当你想让你的新记录去保存一个涉及到多个属性的信息,可能包含多个值,并且你专注于这些数字的和时,是非常有用的)。通过作者的姓名来分组,新的实体被命名为groupedData对于这样的数据,我们然后选择一个新的集合其中包含叫AuthorName的属性,它的值就是分组的主键,另外一个属性是BooksTotalValue ,其中的值为那个作者的书的总和

 

我在这里强调在为了我们的分组数据时用sum方法使用了一个lambda 表达式 ,为了更好的理解那个表达式,我们可以认为是一种类式于C# 2.0 匿名方法。从语法上来讲lambda表达式是一个参数列表紧跟着一个”=>”凭证。在这个表达式被引用的模块中将被执行。(在我们的情况下,将刚刚返回一个Double值)下面的这个连接是更深层次的对lambda表达式的分析

 

我希望这些短例子提供一个关于多种Linq toXML性能的清晰的视角并且您将有现在的好奇心,以进一步探讨利用Linq的功能去从一个XML文件读取数据,甚至 创建,修改或转换XML文件。

原文来之于http://blog.blocks4.net/post/2007/08/Querying-XML-documents-with-LINQ-to-XML.aspx
                                               
                                                           小徐           2008/06/11  晚 23 点  翻译 于 上海

抱歉!评论已关闭.