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

ASP.NET
asp.net(c#)网页跳转七种方法小结
完美解决在ModalPopupExtender中使用CalendarExtender时被层遮挡的问题
ASP.NET、SharePoint中另存文件的长文件名被截断的原因及解决办法
查看Json输出的*最方便*的方法 (转)
asp.net 代码隐藏的编码模型
ajaxpro.dll 控件实现异步刷新页面
asp.net DbProviderFactory的使用-示例
一个简单的asp.net 单点登录实现
jQuery+Ajax用户登录功能的实现
asp.net 弹出对话框返回多个值
.NET 中英文混合验证码实现代码
一个完整的ASP.NET 2.0 URL重写方案[翻译]
asp.net关于onpropertychange和oninput事件实现代码
asp.net gridview指定某一列滚动
Equals和==的区别 公共变量和属性的区别小结
asp.net 合并GridView中某列相同信息的行(单元格)
ASP.NET(C#) 定时执行一段代码
asp.net 预防SQL注入攻击之我见
asp.net下将Excel转成XML档的实现代码
asp.net url分页类代码

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-28   浏览: 68 ::
收藏到网摘: 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中, 一个元素不能包含重复的属性名.

待续!