tags:

views:

297

answers:

2

Hi,

I've got a xml file that looks like this and I'm trying to get all the location attributes in a table cell. I managed to get the title and description but somehow fail to get all the locations within events.

Can someone help me out on this?

Cheers Terry

What I've come up so far is the following

var qListCurrentMonth = (from feed in doc.Descendants("item")
                         select new
                        {
                            title = feed.Element("title").Value,
                            description = feed.Element("description").Value,
                            events = (from ev in feed.Element("events").Elements("location")
                                      select new
                                                 {
                                                     city = ev.Attribute("city")
                                                 }).ToList()
                        });

rptFeedItems.DataSource = qListCurrentMonth;
rptFeedItems.DataBind();

and here the xml

Events Fashion show 1

  <description>item  descr</description>
  <link>http://somelink&lt;/link&gt;

  <events>
    <location city="nyc" date="12.12.08" link="http://www.etc.com" />
    <location city="nyc" date="25.11.08" link="http://www.etc.com" />
    <location city="sfo" date="11.11.08" link="http://www.etc.com" />
    <location city="sfo" date="22.01.08" link="http://www.etc.com" />
    <location city="dal" date="12.12.08" link="http://www.etc.com" />

  </events>
</item>

<item>
  <title>Fashion show 2</title>

  <description>item  descr</description>
  <link>http://somelink&lt;/link&gt;

  <events>
    <location city="nyc" date="12.12.08" link="http://www.etc.com" />
    <location city="nyc" date="25.11.08" link="http://www.etc.com" />
    <location city="sfo" date="11.11.08" link="http://www.etc.com" />
    <location city="sfo" date="22.01.08" link="http://www.etc.com" />
    <location city="dal" date="12.12.08" link="http://www.etc.com" />

  </events>
</item>

and here the repeater

<table border="1">
           <asp:Repeater runat="server" ID="rptFeedItems">
                <ItemTemplate>
                    <tr>
                        <td><%# Eval("title")%></td>
                        <td><%# Eval("description")%></td>
                        <td><%# Eval("events")%></td>
                    </tr>

                </ItemTemplate>
            </asp:Repeater>

        </table>
+1  A: 

I guess you are getting the generic List type instead of the element value. This is because Eval returns the ToString() result and ToString() on a List returns the type. There are several things you can do. One is nest another repeater and bind it to the events property. This is the most clean solution in theory although in this case I doubt it is worth it.

Another thing you can do is accumulate the events property as a string. it can be done like this:

var qListCurrentMonth = 
    (from feed in doc.Descendants("item")
     select new 
     {
         title = feed.Element("title").Value,
         description = feed.Element("description").Value,
         events = 
            (from ev in feed.Element("events").Elements("location")
             select ev.Attribute("city").Value).Aggregate((x,y) => x+ "<br />" + y)
      });

The Aggregate method will accumulate the collection in a single instance. If you have more than 5 events per line average you'd better use StringBuilder as an accumulator (there is overload of Aggregate) for performance reasons (I am sure you know about string vs StringBuilder and performance).

Since you are using .NET 3.5 I would advise using ListView instead of Repeater... like always. Also in this case a GridView may be better since you are representing a table.

Finally - please follow the .NET convention and use PascalCase for property names (i.e. Events instead of events)

Stilgar
Thanks so much Stilgar, I would have never thought about using the aggregate method.
Terry Marder
+1  A: 

If you just want to list the city codes in your events cell:

var qListCurrentMonth =
    from feed in doc.Descendants("item")
    let cities =
        (from location in feed.Element("events").Elements("location")
         select location.Attribute("city").Value)
         .ToArray())
    select new
    {
        title = feed.Element("title").Value,
        description = feed.Element("description").Value,
        events = string.Join(", ", cities)
    });

Stilgar's Aggregate method is a great suggestion as well.

Joe Chung