linq-XElement筛选排序问题

问题描述

XElement筛选排序问题
<Last-Modified>  <Record>    <Path>/kcs/scenes/TitleMain.swf</Path>    <Time>Wed 23 Apr 2014 07:37:36 GMT</Time>    <Version>2.0.0</Version>  </Record>  <Record>    <Path>/kcs/resources/swf/font.swf</Path>    <Time>Wed 23 Apr 2014 05:05:30 GMT</Time>    <Version>2.0.0</Version>  </Record>  ...(一共7个<Record>)</Last-Modified>

我需要对上面的XML内容根据Path元素对Record元素进行排序,并保存到文件。

首先是加载文件,没有任何问题

const string _RootName = ""Last-Modified"";const string _ItemElm = ""Record"";const string _ElmPath = ""Path"";var fileXML = XDocument.Load(filepath);fileXML.Root.Name = _RootName;

然后筛选和排序,最初我是想这样写的:

var elms = fileXML.Root        .Elements(_ItemElm)        .OrderBy(elm => elm.Element(_ElmPath).Value)        .ToArray();fileXML.Root.Elements().Remove();fileXML.Root.Add(elms);

结果各种错误,只好一点一点拆开来,一步一步分析

首先是Elements()筛选,从这里就开始有问题了

var elms1 = fileXML.Root.Elements(_ItemElm);Log.Note(""fileXML.Root.Elements(_ItemElm): "" + elms1.Count().ToString());

日志输出结果是:fileXML.Root.Elements(_ItemElm): 0

搞了半天没搞懂为什么返回0个结果。
我只好退而求其次,**用Where()筛选**了。

var elms2 = fileXML.Root.Elements().Where(elm => elm.Name == _ItemElm);Log.Note(""fileXML.Root.Elements().Where(_ItemElm): "" + elms2.Count().ToString());

花了半天才发现Name属性是XName,不能直接和string比较,所以加上了ToString();

var elms2 = fileXML.Root.Elements().Where(elm => elm.Name.ToString() == _ItemElm);Log.Note(""fileXML.Root.Elements().Where(_ItemElm): "" + elms2.Count().ToString());

用了ToString()之后,输出为:fileXML.Root.Elements().Where(_ItemElm):7

筛选完成之后是排序

var elms4 = elms2.OrderBy(elm => elm.Element(_ElmPath).Value);var elms = elms4.ToArray();

然后就在ToArray()发生NullReferenceException异常了
然后我就不明白了,为什么OrderBy返回的是null。

所以总结一下,有两个地方不明白:

  • 一个是Elements(_ItemElm)为什么返回0个结果
  • 一个是OrderBy()为什么返回null

解决方案

use Descendants instead of Elements

时间: 2024-09-16 03:10:52

linq-XElement筛选排序问题的相关文章

教你如何实现LINQ查询语句

实现LINQ查询语句有三个步骤,他们分别是获取数据源(任何查询的必备工作).创建查询.执行查询 .本文就从这三个方面对实现LINQ查询语句做简单的介绍. 示例: class IntroToLINQ { static void Main() { //获取数据源(此处由一个数组充当) int[] numbers = new int[7]{0,1,2,3,4,5,6}; //创建查询(numQuery 是 IEnumerable 类型) var numQuery = from num in numbe

Linq to XML 问题!!!

问题描述 写不到xml的<newsid>节点中!!!前台如下:姓名:<asp:TextBoxID="txtName"runat="server"></asp:TextBox>  年龄:<asp:TextBoxID="txtAge"runat="server"></asp:TextBox>  薪水:<asp:TextBoxID="txtSalary&qu

Dbml文件提取建表TSql-CodeSmith

     在昨天一个大学师弟,他问我能不能将LinqToSql文件转化为创建表的TSql语句,他是刚开始学习.NET,所以在网上下些示例看,但苦于没有数据库.所以就有了这一篇博客,作为我的Code生成技术的CodeSimth的最后一篇示例.在下一步Code 生成技术将转到Microsoft的T4模板,Code生成技术目前完成的有CodeDom,CodeSmith模板,高手请不要拍砖,请直接跳过.      在Linq2Sql的Dbml文件其实就是一个Xml文件,记录着数据库与生成Linq2Sql

探索 ASP.NET Futures

如果你在使用ASP.NET站点,同时又希望它Search Engine Friendly一些,很可能你就希望它有一个Sitemaps.在这里我们说的不是ASP.NET的SiteMap,而是Sitemaps.org定义的基于XML的Sitemaps协议,注意这两个名字的大小写以及单复数,之后我都会这样区分它们.Sitemaps协议有点类似RSS或者Atom,只不过它描述的不是最近的内容更新,而是整个站点的地图,主要用来描述特定URL的重要程度.更新时间及频率等.搜索引擎如Google是支持Site

《圣殿祭司的ASP.NET4.0专家技术手册》----2-10 匿名类型

2-10 匿名类型 圣殿祭司的ASP.NET4.0专家技术手册C# 2.0有匿名方法(Anonymous Method),而C# 3.0又新增了"匿名类型(Anonymous Types)",它的目的是"提供一个简单的途径将一组只读的属性封装在一个对象之中",且在第一时间不必声明其明确类型. 2-10-1 匿名类型的由来 以下是一段匿名类型的变量声明,并以new的关键字进行初始化: 为什么要叫"匿名类型"?原因有几个: (1)传统多半是先建立一个

话说索引器、foreach和集合初始化器

索引器 在使用集合类时我们经常用到索引器,例如List集合,我们使用int数字作为索引器参数,而字典集合我们可以使用任何对象作为索引器参数. 在我们自己定义的类中使用索引器的情况也许不多,现在举例详细说明一下.假设我们定义首都类( Capital ): public class Capital { /// <summary> /// 名称 /// </summary> public string Name { get; set; } /// <summary> ///

一起谈.NET技术,话说索引器、foreach和集合初始化器

索引器 在使用集合类时我们经常用到索引器,例如List集合,我们使用int数字作为索引器参数,而字典集合我们可以使用任何对象作为索引器参数. 在我们自己定义的类中使用索引器的情况也许不多,现在举例详细说明一下.假设我们定义首都类( Capital ): public class Capital {/// <summary>/// 名称/// </summary> public string Name { get; set; } /// <summary>/// 定位//

Linq学习(4) 投影、筛选和排序

这里简单介绍Linq的投影.筛选和排序子句. Select select 在一个集合序列按给定的条件进行投影,select 可以返回组合的筛选结果,返回匿名类型,对返回结果进行操作,返回组合的子查询结果等等. select 的方法定义原形为: public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TRes

C# Linq筛选datatable后adapt.update的问题

问题描述 DataTabledt=newDataTable();DataTabledtnew=dt_OD_BAS.Clone();IEnumerable<DataRow>rows=fromdt1indt_OD_BAS.AsEnumerable()selectdt1;foreach(DataRowdrinrows){dtnew.ImportRow(dr);}intidtrows=rows.Count();if(idtrows==0){dt.Clear();}else{dt=rows.CopyTo