LINQ to XML递归查询

我有一个像文档树一样的xml站点地图,它看起来像这样:

 FileName   Admin  FileName  FileName FileName  FileName    

*请注意,这不是我的实际xml文件。 实际的xml文件太大而无法显示。 基本上你需要消除的是,有可能存在“X”数量的文件夹彼此嵌套,并且在这些文件夹中的某些点上,可能存在“X”数量的文件以及子文件夹。

此外, 某些文件夹具有安全性,该文件夹由文件夹中的所有内容 (文件,子文件夹,子文件夹中的文件等)inheritance。 我试图提出一个LINQ to XML查询,以获得基于该文件GUID的给定文件的安全性,它适用于level-1和level-2文件,但是当我尝试在一个文件上运行查询时文件是3个文件夹深,它失败,我得到一个nullreferenceexception。 这是我正在使用的查询:

 XDocument sitemap = XDocument.Load(HttpContext.Current.Server.MapPath("/.../sitemap.xml")); XElement fileFromMap = sitemap.Descendants("File").Where( file => file.Attribute("GUID").Value == guid).First(); XElement currentFile = new XElement("File", fileFromMap.Value, fileFromMap.Ancestors("Folder").SelectMany( folder => { XElement security = folder.Element("Security"); return (security != null ? security.Elements("Role") : null); })); 

*和信用到期的信用,我在这里得到了这个查询

nullreferenceexception发生在currentFile变量的声明中,我不知道为什么。 我确保Guids匹配……并且因为正确声明了fileFromMap ,我知道我的文件正在被找到。 我假设这里需要做的是更好地检查父文件夹的安全性。 查询可以在找到任何安全性后立即停止,因为站点的设置方式应该没有冲突的安全声明。 (例如,没有已定义安全性的文件夹将位于已定义安全性的文件夹中)

如果我错了,这不是我需要做的,请提供您可能提出的任何建议,并随意更改此问题的标题,以便更好地记录它。

(如果您在之前的问题中留下我的评论,那可能是最好的,但我现在可以回答这个问题,因为它已发布;)

我提供的代码中有一个错误:我认为SelectMany()以与XElement.Add()相同的方式折叠了null项,而我错了。 如果祖先链中有一个没有角色的文件夹, SelectMany()将抛出NullReferenceException

我们只需要为它提供一个空的可枚举的XElement来解决问题:

 XElement currentFile = new XElement("File", fileFromMap.Value, fileFromMap.Ancestors("Folder").SelectMany( folder => { XElement security = folder.Element("Security"); return (security != null ? security.Elements("Role") : new XElement[0]); })); 

我将使用反向链接更新我的原始答案。