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

时间:2015-12-08 07:06:13

标签: c# asp.net linq

<?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();

上面的查询只返回第一个父项,而不是子项。还没有加载其他父级。

1 个答案:

答案 0 :(得分:0)

我发现您的代码存在一些问题,首先我不确定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");