我有一个 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”个文件以及子文件夹。
此外,某些 文件夹具有安全性,该文件夹中的所有内容(文件、子文件夹、子文件夹中的文件等)都继承了该安全性。我正在尝试提出一个 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
空引用异常发生在 currentFile
变量的声明中,我不确定为什么。我已确保 Guid 匹配...并且由于 fileFromMap
被正确声明,我知道我的文件正在被发现。我假设这里需要做的是更好地递归检查父文件夹的安全性。一旦发现任何安全性,查询就可以停止,因为站点的设置方式不应该有冲突的安全声明。 (例如,已定义安全性的文件夹将不会位于已定义安全性的文件夹内)
如果我错了,这不是我需要做的,请提供您可能有的任何建议,并随时相应地更改此问题的标题以便更好地记录它。
最佳答案
(如果您在上一个问题中给我留下评论可能会更好,但既然它已发布,我不妨回答这个问题;)
我提供的代码有一个错误:我认为 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]);
}));
我将使用反向链接更新我的原始答案。
关于c# - LINQ to XML 递归查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6836187/