c# - LINQ to XML 递归查询

标签 c# xml linq linq-to-xml

我有一个 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() 以相同的方式折叠 nullXElement.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/

相关文章:

c# - 避免 LINQ to SQL 中的 2100 个参数限制

c# - XSLT排序,选择next nearest

xml - 使用 Go 解析巨大的 XML 文件

c# - LINQ 查询性能低下

c# - 向字符串添加回车符

c# - 方法还是属性?

c# - OR 正则表达式中的表达式?

c# - 从数据库读取数据时让 WPF UI 负责

asp.net-mvc - ASP.NET MVC - 以 HTML 或 XML 形式返回数据

c# - 在列表集合中查找重复项