我有一个像文档树一样构建的xml站点地图,如下所示:
<Site>
<File GUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx">FileName</file>
<Folder name="FolderName">
<Security>
<Role>Admin</role>
</Security>
<File GUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx">FileName</file>
<Folder name="subFoler">
<File GUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx">FileName</file>
<File GUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx">FileName</file>
<Folder>
<File GUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx">FileName</file>
</Folder>
</Folder>
</Folder>
*请注意,这是不我的实际xml文件。实际的xml文件太大而无法显示。基本上你需要消除的是,有可能存在“X”数量的文件夹彼此嵌套,并且在这些文件夹中的某些时候,可能存在“X”个文件以及子文件夹。 / p>
此外,某些文件夹具有安全性,该文件夹由文件夹中的所有继承(文件,子文件夹,子文件夹中的文件等)。我试图提出一个LINQ to XML查询,以获得基于该文件GUID的给定文件的安全性,它适用于level-1和level-2文件,但是当我尝试运行查询时文件是3个文件夹深,它失败,我得到一个nullreference异常。这是我正在使用的查询:
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);
}));
*并且在信用到期的情况下,我收到了此查询here
null引用异常发生在currentFile
变量的声明中,我不知道为什么。我确保Guids匹配......并且因为fileFromMap
被正确声明,我知道我的文件正在被找到。我假设这里需要做的是更好地检查父文件夹的安全性。查询可以在找到任何安全性后立即停止,因为站点的设置方式应该没有冲突的安全声明。 (例如,没有已定义安全性的文件夹将位于已定义安全性的文件夹中)
如果我错了,这不是我需要做的,请提供您可能提出的任何建议,并随意更改此问题的标题,以便更好地记录。
答案 0 :(得分:2)
(如果您在之前的问题中留下评论,那可能是最好的,但我现在也可以回答这个问题,因为它已发布;)
我提供的代码中存在错误:我认为SelectMany()
以与null
相同的方式折叠了XElement.Add()
个项目,而我错了。如果祖先链中有一个没有角色的文件夹,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]);
}));
我会用反向链接更新我的原始答案。