当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > LINQ学习笔记:导航和查询X-DOM

ASP.NET
[EnterpriseServices]利用assembly定义我们的组件在COM+中的注册方式
crystal reports for Visual Studio .NET(webformsample)
XML指南:微软的XML解析器
展现C# 清单5.10 生成exe文件执行的问题
vb.net 读写xml方法(1)
选择文件夹的对话框控件c#
特洛伊木马服务器源代码(C#)
上传图片画带阴影的水印.(C#)
vb.net读写xml(2)--实现datagrid与xml的沟通(原创)
列出所有的sheet,然后点击其中的一个,自动跳过去
从VB中的Datagride中向excel导入数据
XML指南:XML CDATA
XML指南:XML编码
XMLDOM对象方法:Document对象方法
XMLDOM对象方法:对象事件
XMLDOM对象方法:对象属性
[一个登录窗体的完整范例,包括登录,密码更改,输入错误三次退出]
[关于判断输入数据是否在数据库中的方法。]
[VBA]office中内建的faceid所对应的图标
web组件设计,利用接口(IPostBackDataHandler)产生数据回传的问题

ASP.NET 中的 LINQ学习笔记:导航和查询X-DOM


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-28   浏览: 239 ::
收藏到网摘: n/a

导航/查询X-DOM

就像你可能期望的那样, XNode和XContainer类定义了方法和属性来测量X-DOM树. 与常规的DOM不同的是, 这些函数并不会返回实现了IList<T>的集合, 而是返回了一个单一值或者一个实现了IEnumerable<T>的序列. 基于这个你可以执行一个LINQ查询或者使用foreach来做枚举. 这同时也允许你使用熟悉的LINQ查询语法来执行简单的导航任务或者高级查询.

在X-DOM中, 元素和属性名都是大小写敏感的, 这与XML是一致的.

FirstNode, LastNode与Nodes

FirstNode与LastNode允许你直接访问第一个或者最后一个子节点; Nodes返回所有的子节点并形成一个序列. 这三个方法只用于直系的后代节点.

检索元素

Elements方法返回类型为XElement的子节点. 例如:

 1: var bench = new XElement ("bench",
 2: new XElement ("toolbox",
 3: new XElement ("handtool", "Hammer"),
 4: new XElement ("handtool", "Rasp")
 5: ),
 6: new XElement ("toolbox",
 7: new XElement ("handtool", "Saw"),
 8: new XElement ("powertool", "Nailgun")
 9: ),
 10: new XComment ("Careful with the nailgun")
 11: );
 12:
 13: foreach (XElement e in bench.Elements( ))
 14: Console.WriteLine (e.Name + "=" + e.Value);
 15:
 16: // 结果: toolbox=HammerRasp
 17: toolbox=SawNailgun

以下的LINQ查询用于查询包含nail gun的toolbox:

 1: IEnumerable<string> query =
 2: from toolbox in bench.Elements( )
 3: where toolbox.Elements( ).Any
 4: (tool => tool.Value == "Nailgun")
 5: select toolbox.Value;
 6:
 7: RESULT: { "SawNailgun" }

Elements等价于Nodes上面的LINQ查询, 我们之前的查询也可以被写为:

 1: from toolbox in bench.Nodes().OfType<XElement>()
 2: where ...

接下来的例子使用一个SelectMany查询检索hand tools:

 1: IEnumerable<string> query =
 2: from toolbox in bench.Elements( )
 3: from tool in toolbox.Elements( )
 4: where tool.Name == "handtool"
 5: select tool.Value;
 6:
 7: RESULT: { "Hammer", "Rasp", "Saw" }

Elements也可以只返回给定名称的元素, 例如:

 1: int x = bench.Elements ("toolbox").Count(); // 2

这等价于:

 1: int x = bench.Elements()
 2: .Where (e => e.Name == "toolbox")
 3: .Count(); // 2
 4:

Elements还定义了一个扩展方法接受IEnumerable<XContainer>参数. 更精确的说, 它接受了此种类型的参数:

 1: IEnumerable<T> where T : XContainer

这让其可以和元素序列一起工作, 使用这个方法我们可以重写查找hand tools的查询:

 1: from tool in bench.Elements ("toolbox")
 2: .Elements ("handtool")
 3: select tool.Value.ToUpper( );

第一个Elements绑定到XContainer上, 第二个则绑定到扩展方法上.

读取一个单一的元素

方法Element(单数)返回匹配给定名称的第一个元素. Element对于简单的导航是非常有用的, 例如:

 1: var settings = XElement.Load ("databaseSettings.xml");
 2:
 3: string cx = settings.Element ("database")
 4: .Element ("connectString")
 5: .Value;

Element的作用相当于调用Elements然后再应用LINQ的FirstOrDefault并给定一个名称作为匹配断言. 如果没有任何元素匹配到, 则Element返回null.

如果元素xyz不存在, 那么Element(”xyz”).Value将会抛出一个NullReferenceException异常. 如果你倾向于使用null代替异常, 可以将XElement转换成string而不是调用它的Value属性, 如下:

 1: string xyz =
 2: (string) settings.Element("xyz");

XElement定义了一个显示的string转换正式为了这个目的.

递归功能

XContainer同时也定义了Descendants和DescendantNodes方法, 它们递归地返回子元素或者子节点.Descendant接受一个可选的元素名, 会到我们之前的例子, 我们可以使用Descendants去查找所有的hand tools:

 1: Console.WriteLine
 2: (bench.Descendants ("handtool").Count( )); // 3

不管是父节点还是叶节点都包含在整体横切中. 以下的查询取得所有包含单词”careful”, 存在于X-DOM任何地方的注释节点:

 1: IEnumerable<string> query =
 2: from c in bench.DescendantNodes( ).OfType<XComment>( )
 3: where c.Value.Contains ("careful")
 4: orderby c.Value
 5: select c.Value;

查询父节点

所有的XNodes都有一个Parent属性和AncestorXX的方法用于父节点导航. 一个父亲节点永远是一个XElement.

如果x是一个XElement, 以下代码打印true:

 1: foreach (XNode child in x.Nodes( ))
 2: Console.WriteLine (child.Parent == x);

如果x是一个XDocument的话, XDocument有点独特, 它永远不能作为任何节点的父亲节点. 为了访问XDocument,应该使用Document属性, 这只争对X-DOM树上的任意对象可以工作.

Ancestors返回一个序列其第一个元素是Parent, 下一个元素则是Parent.Parent, 依次类推直到根元素.

你还可以使用LINQ查询AncestorsAndSelf().Last()来取得输入序列的根元素. 另外一种方法是调用Document.Root, 但只有当XDocument呈现的时候才能工作.

对等节点导航

使用PreviousNode和NextNode(FirstNode / LastNode),我们可以使用一个linked list横贯所有的节点. 这并不是巧合, 在内部, Nodes实际上就是存储在一个linked list.

属性导航

XAttributes定义了PreviousAttribute和NextAttribute, Parent也是一样.

Attributes方法接受了一个名称并返回包含0或1个元素的序列; 在XML中, 一个元素不能包含重复的属性名.

待续!