如何在 asp.net 中使用 LINQ to XML 为特定角色创建分层菜单结构

本文关键字:XML 定角色 创建 结构 菜单 分层 to LINQ asp net | 更新日期: 2023-09-27 18:26:13

<?xml version="1.0" encoding="utf-8" ?>
<Menu>
  <Role Id="Admin">
    <ParentItems>
      <ParentItem Id="1" DisplayText="Home" Url="" >
      </ParentItem>
      <ParentItem Id="2" DisplayText="Proposal" Url="">
        <ChildItems>
          <ChildItem Id="1" DisplayText="Create" Url=""/>
          <ChildItem Id="2" DisplayText="Search" Url=""/>
        </ChildItems>
      </ParentItem>
    </ParentItems>
  </Role>
  <Role Id="User">
    <ParentItems>
      <ParentItem Id="1" DisplayText="Home" Url="" />
      <ParentItem Id="2" DisplayText="Proposal" Url="">
        <ChildItems>
          <ChildItem Id="1" DisplayText="Create" Url=""/>
          <ChildItem Id="2" DisplayText="Search" Url=""/>
        </ChildItems>
      </ParentItem>
      <ParentItem Id="3" DisplayText="Profile" Url="">
        <ChildItems>
          <ChildItem Id="1" DisplayText="Extended Profile" Url=""/>
        </ChildItems>
      </ParentItem>
    </ParentItems>
  </Role>
</Menu>
public class ChildMenuVm
{
    public string MenuId { get; set; }
    public string DisplayText { get; set; }
    public string Url { get; set; }
}
public class ParentMenuVm
{
    public string MenuId { get; set; }
    public string DisplayText { get; set; }
    public string Url { get; set; }
    public IList<ChildMenuVm> ChildMenuVms{ get; set; }
    public ParentMenuVm()
    {
        ChildMenuVms= new List<ChildMenuVm>();
    }
}
public class MenuViewModel
{
    public List<ParentMenuVm> MenuList { get; set; }
    public MenuViewModel()
    {
        MenuList = new List<ParentMenuVm>();
    }
}

用于 LINQ 查询的函数

menuVm.MenuList = (from items in xElement.Elements("Role")
                          where items.Attribute("Id").Value == role
                          from parent in items.Elements("ParentItems")
                          select new ParentMenuVm()
                          {
                              MenuId = parent.Element("ParentItem").Attribute("Id").Value.ToString(),
                              DisplayText = parent.Element("ParentItem").Attribute("DisplayText").Value.ToString(),
                              Url = parent.Element("ParentItem").Attribute("Url").Value.ToString(),
                              ChildMenuVms = (from child in items.Elements("ChildItems")
                                              select new ChildMenuVm()
                                              {
                                                  MenuId = child.Element("ChildItem").Attribute("Id").Value.ToString(),
                                                  DisplayText = child.Element("ChildItem").Attribute("DisplayText").Value.ToString(),
                                                  Url = child.Element("ChildItem").Attribute("Url").Value.ToString(),
                                              }).ToList()
                          }
                           ).ToList();

上面的查询只返回第一个父项,而不是子项。此外,不会加载其他父项。

如何在 asp.net 中使用 LINQ to XML 为特定角色创建分层菜单结构

我看到你的代码几乎没有问题,首先我不确定你已经有什么xElement。其次,您只获得第一人称,因为您正在查询items.Elements("ParentItems")而我只看到您的 XML 中的ParentItems节点。第三个问题在这里:查询中的items.Elements("ChildItems") items表示Role的元素,但它不直接包含任何ChildItems而是存在于ParentItem中。此外,您总是使用 Element 进行查询,然后Element如果 XML 中缺少任何元素,可能会导致Null Reference Exception。我宁愿这样做:-

menuVm.MenuList = (from role in xdoc.Root.Elements("Role")
                   where (string)role.Attribute("Id") == role
                   from parentItems in role.Element("ParentItems").Elements("ParentItem")
                   let ChildItems = parentItems.Descendants("ChildItem")
                   select new ParentMenuVm
                       {
                          MenuId = (string)parentItems.Attribute("Id"),
                          DisplayText = (string)parentItems.Attribute("DisplayText"),
                          Url = (string)parentItems.Attribute("Url"),
                          ChildMenuVms = (from child in ChildItems
                                   select new ChildMenuVm 
                                    {
                                      MenuId = (string)child.Attribute("Id"),
                                      DisplayText = (string)child.Attribute("DisplayText"),
                                      Url = (string)child.Attribute("Url")
                                    }).ToList()
                        }).ToList();

这里xdoc是XDocuemnt对象:-

XDocument xdoc = XDocument.Load(@"YourXMlFilePath");