2009-08-01 57 views
1

我有一个xml文件,看起来像这样,我试图获取表格单元格中的所有位置属性。我设法得到标题和描述,但不知何故无法获得事件中的所有位置。与linq在中继器嵌套的XML

有人可以帮我解决这个问题吗?

干杯 特里

我想出迄今已是以下

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

这里的XML

活动 时装秀1

<description>item descr</description> 
    <link>http://somelink</link> 

    <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</link> 

    <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> 

这里的中继

<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

您是否考虑过使用XSLT? :-) – 2009-08-01 12:57:02

+0

我无法想象一个人如果可以使用LINQ to XML就想使用XSLT的情况。这就是说,XSLT有合法的理由,比如当需要与非.NET系统互操作时,以及稍后应该向系统提供转换时,并且允许LINQ to XML由于可以使用而导致安全风险时注入任意代码。 – Stilgar 2009-08-01 16:48:25

回答

1

我猜你所得到的泛型列表类型而不是元素值。这是因为Eval返回ToString()结果而List上的ToString()返回该类型。有几件事你可以做。一个是嵌套另一个中继器并将其绑定到events属性。这是理论上最干净的解决方案,虽然在这种情况下我怀疑这是值得的。

你可以做的另一件事是积累events属性作为一个字符串。它可以这样完成:

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) 
     }); 

Aggregate方法将在一个实例中累积集合。如果你的平均每条线有5个以上的事件,你最好使用StringBuilder作为累加器(有Aggregate的重载),这是出于性能方面的原因(我相信你知道string vs StringBuilder和性能)。

既然你使用的是.NET 3.5,我会建议使用ListView而不是Repeater ...就像往常一样。同样在这种情况下,GridView可能会更好,因为您代表的是表格。

最后 - 请遵循.NET约定,并使用PascalCase的属性名称(即事件,而不是事件)

1

如果你只是想列出您的活动单元格的城市代码:

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的Aggregate方法也是一个很好的建议。