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

ASP.NET
asp.net GridView控件中模板列CheckBox全选、反选、取消
asp.net GridView 删除时弹出确认对话框(包括内容提示)
asp.net DropDownList 三级联动下拉菜单实现代码
asp DataTable添加列和行的三种方法
Asp.net 页面调用javascript变量的值
asp.net 长文章通过设定的行数分页
asp.net 定时间点执行任务的简易解决办法
asp.net 页面延时五秒,跳转到另外的页面
asp.net 动态输出透明gif图片
asp.net DataList与Repeater用法区别
asp.net Javascript获取CheckBoxList的value
asp.net程序在调式和发布之间图片路径问题的解决方法
asp.net下生成英文字符数字验证码的代码
asp.net 页面版文本框智能提示JSCode (升级版)
ASP.NET URL伪静态重写实现方法
ASP.NET 2.0 中Forms安全认证
asp.net 动态添加多个用户控件
asp.net Repeater显示父子表数据,无闪烁
asp.net 无法获取的内部内容,因为该内容不是文本 的解决方法
asp.net GridView排序简单实现

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


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

待续!