【问题标题】:nested xml with linq in repeater中继器中带有 linq 的嵌套 xml
【发布时间】:2009-08-01 12:44:10
【问题描述】:

我有一个看起来像这样的 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>

【问题讨论】:

  • 您考虑过使用 XSLT 吗? :-)
  • 如果他可以使用 LINQ to XML,我无法想象一个人会想要使用 XSLT 的情况。话虽这么说,XSLT 有正当的理由,比如何时需要与非 .NET 系统进行互操作,何时应在稍后向系统提供转换,并且允许 LINQ to XML 可能存在安全风险,因为它可以使用注入任意代码。

标签: c# xml linq


【解决方案1】:

我猜你得到的是通用 List 类型而不是元素值。这是因为 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 和性能),您最好使用 StringBuilder 作为累加器(存在 Aggregate 的重载)。

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

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

【讨论】:

  • 非常感谢 Stilgar,我从没想过使用聚合方法。
【解决方案2】:

如果您只想在活动单元格中列出城市代码:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多