简体   繁体   中英

LINQ to XML Grouping

I'm trying to create a menu for my web site programmatically from an xml file. The menu has three links in the menu bar that expand on a mouse over event and reveal content (links and images). The xml file has MenuItem nodes which correspond to the three links in the menu bar and MenuContent nodes which correspond to the mouse over content. In psuedo-code, here's what I'd like to do:

  1. Read the xml file.
  2. Group the xml file by MenuItem nodes.
  3. Populate the outer repeater with MenuItem data.
  4. For each MenuItem node, populate the inner repeater with MenuContent data.

My problem is that I don't know how to properly group the MenuItem nodes and then populate the inner repeater. The C# code for grouping was something that worked in an older project, but doesn't work in this case. I included it just to get some code out there.

How can I fix the C# code to group by the MenuItem nodes and populate the inner repeater?

<asp:Repeater ID="Repeater1" runat="server">
    <ItemTemplate>
        <div>
            <asp:Repeater ID="Repeater2" runat="server">
                <ItemTemplate>
                    <div class="menuContent">
                        <div>
                            <div class="menuContentItem">
                                <a href='<%# Eval("LinkUrl") %>'>
                                    <table>
                                        <tr>
                                            <td align="center" valign="middle">
                                                <img src='<%# Eval("ImageUrl") %>' alt='<%# Eval("ImageToolTip") %>' />
                                            </td>
                                            <td align="left" valign="top">
                                                <div><%# Eval("Title") %></div>
                                                <div><%# Eval("Description") %></div>
                                            </td>
                                        </tr>
                                    </table>
                                </a>
                            </div>
                        </div>
                    </div>
                </ItemTemplate>
            </asp:Repeater>
        </div>
    </ItemTemplate>
</asp:Repeater>


var menuPath = Server.MapPath("~/Menu.xml");
var xDocument = XDocument.Load(menuPath);
var menuItems = new List<MenuItem>();

var groups = (from x in xDocument.XPathSelectElements("Menu")
              group x by new
              {
                  Description = x.Descendants("Description").FirstOrDefault().Value,
                  ImageToolTip = x.Descendants("ImageToolTip").FirstOrDefault().Value,
                  ImageUrl = x.Descendants("ImageUrl").FirstOrDefault().Value,
                  LinkUrl = x.Descendants("LinkUrl").FirstOrDefault().Value,
                  Title = x.Descendants("Title").FirstOrDefault().Value
              } into g
              select g).ToDictionary(g => g.Key, g => g.ToArray());


Repeater1.DataSource = groups;
Repeater1.DataBind();



<?xml version="1.0" encoding="utf-8" ?>

<Menu>
    <MenuItem>
        <MenuContent>
            <Title>Title 1a</Title>
            <Description>Description 1a</Description>
            <LinkUrl>Link URL 1a</LinkUrl>
            <ImageUrl>Image URL 1a</ImageUrl>
            <ImageToolTip>Image ToolTip 1a</ImageToolTip>
        </MenuContent>
        <MenuContent>
            <Title>Title 2a</Title>
            <Description>Description 2a</Description>
            <LinkUrl>Link URL 2a</LinkUrl>
            <ImageUrl>Image URL 2a</ImageUrl>
            <ImageToolTip>Image ToolTip 2a</ImageToolTip>
        </MenuContent>
        <MenuContent>
            <Title>Title 3a</Title>
            <Description>Description 3a</Description>
            <LinkUrl>Link URL 3a</LinkUrl>
            <ImageUrl>Image URL 3a</ImageUrl>
            <ImageToolTip>Image ToolTip 3a</ImageToolTip>
        </MenuContent>
    </MenuItem>
    <MenuItem>
        <MenuContent>
            <Title>Title 1b</Title>
            <Description>Description 1b</Description>
            <LinkUrl>Link URL 1b</LinkUrl>
            <ImageUrl>Image URL 1b</ImageUrl>
            <ImageToolTip>Image ToolTip 1b</ImageToolTip>
        </MenuContent>
        <MenuContent>
            <Title>Title 2b</Title>
            <Description>Description 2b</Description>
            <LinkUrl>Link URL 2b</LinkUrl>
            <ImageUrl>Image URL 2b</ImageUrl>
            <ImageToolTip>Image ToolTip 2b</ImageToolTip>
        </MenuContent>
        <MenuContent>
            <Title>Title 3b</Title>
            <Description>Description 3b</Description>
            <LinkUrl>Link URL 3b</LinkUrl>
            <ImageUrl>Image URL 3b</ImageUrl>
            <ImageToolTip>Image ToolTip 3b</ImageToolTip>
        </MenuContent>
    </MenuItem>
</Menu>

Instead of using aggregation you could try the following:

var groups = from x in xd.Element("Menu").Elements("MenuItem")
             select new
             {
                 Items = (from c in x.Elements("MenuContent")
                          select new
                          {
                              Description = c.Element("Description").Value,
                              ImageToolTip = c.Element("ImageToolTip").Value,
                              ImageUrl = c.Element("ImageUrl").Value,
                              LinkUrl = c.Element("LinkUrl").Value,
                              Title = c.Element("Title").Value
                          }).ToList()
             };

and then change the Repeater2 tag to:

<asp:Repeater ID="Repeater2" DataSource='<%# Eval("Items") %>' runat="server">

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM