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

ASP.NET
C# Quoted-Printable编码、解码
asp.net Google的translate工具翻译 API
.NET读取所有目录下文件正则匹配文本电子邮件
asp.net 半角全角转化工具
AjaxControlToolKit 显示浏览者本地语言的方法
asp.net HTML文件上传标签
ASP.NET 绑定DataSet中的多个表
ASP.NET 重定向的几种方法小结
Asp.Net 重定向必须要知道的一些资料
ASP.NET 导出到Excel时保留换行的代码
Asp.Net Cache缓存使用代码
document.getElementsByName和document.getElementById 在IE与FF中不同实现
GridView单元格合并
asp.net 大文件上传控件
asp.net 日期函数 某月的第一天和最后一天的日期
asp.net 时间类 一周的周一和周末的日期
C# javaScript函数的相互调用
asp.net membership 密码重设
"虚拟路径"..."映射到另一个应用程序,这是不允许的!
如何传值在2个页面之间 要求不刷新父页面,并且不能用Querystring传值

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


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

待续!