如何将xml子节点读入ASP.NET转发器

时间:2010-07-29 15:29:48

标签: c# asp.net xml

我正在使用xmlreader读取XML,然后将xml绑定到Repeater

这是背后的代码:

            XmlReaderSettings settings = new XmlReaderSettings();
        settings.ProhibitDtd = false;

        XmlReader xmlData = XmlReader.Create(webClient.OpenRead(requestUrl), settings);

        try
        {
            xmlData.ReadToFollowing("SearchResults");
            Label1.Text = xmlData.GetAttribute("TotalCount");
            int numberResults = Convert.ToInt32(xmlData.GetAttribute("TotalCount"));
            if (numberResults > 0)
            {
                DataSet ds = new DataSet();
                ds.ReadXml(xmlData);
                Repeater1.DataSource = ds.Tables[1];
                Repeater1.DataBind();
            }
            else
            {
                Repeater1.DataSource = null;
                Repeater1.DataBind();
            }
        }

这是转发器

        <asp:Repeater ID="Repeater1" runat="server">
    <HeaderTemplate><b>Results</b><br /><br /></HeaderTemplate>
    <ItemTemplate>
   <a href="<%#DataBinder.Eval(Container.DataItem, "Url")%>">
    <%#DataBinder.Eval(Container.DataItem, "Title")%></a><br />
    </ItemTemplate>
    </asp:Repeater>

xml看起来像:

  <SearchResults PageSize="1" PageIndex="0" TotalCount="155">
<SearchResult>
  <ContentId>2458</ContentId>
  <Title>Component description</Title>
  <Url>http://whatever/19/p/1537/2458.aspx</Url>
  <Date>2009-06-10T09:34:00+01:00</Date>
  <ContentType>forum</ContentType>
  <Tags>
    <Tag>Component</Tag>
  </Tags>
  <Users>
    <User>
      <Id>2533</Id>
      <DisplayName>Haubent</DisplayName>
      <Username>Haubent</Username>
    </User>
  </Users>
  <IndexedAt>2010-07-29T15:40:52.414+01:00</IndexedAt>
</SearchResult>

到目前为止一切顺利。

但是 - 我希望能够在我的转发器项模板中显示DisplayName节点的内容。

我试过

<%#DataBinder.Eval(Container.DataItem, "DisplayName")%>

<%#DataBinder.Eval(Container.DataItem, "Users.User.DisplayName")%>

但是我收到了错误:

  

System.Web.HttpException:DataBinding:'System.Data.DataRowView'不包含名为'Users'的属性。

如何获取DisplayName?

3 个答案:

答案 0 :(得分:2)

我认为最好(也是最自然)的方法是使用Linq To XML。 您可以通过以下方式更改try块:

try
{
    xmlData.ReadToFollowing("SearchResults");
    Label1.Text = xmlData.GetAttribute("TotalCount");
    int numberResults = Convert.ToInt32(xmlData.GetAttribute("TotalCount"));
    if (numberResults > 0)
    {
        XDocument xml = XDocument.Parse(xmlData.ReadOuterXml());

        Repeater1.DataSource = xml.Element("SearchResults").Elements("SearchResult");
        Repeater1.DataBind();
    }
    else
    {
        Repeater1.DataSource = null;
        Repeater1.DataBind();
    }
}
catch 
{
    // do some catch
}

将XElement集合传递给de repeater。然后你可以声明一个类似于这个的OnRepeaterDataBound方法:

protected void Repeater1_OnItemDataBound(object sender, RepeaterItemEventArgs e) 
{
    if ((e.Item.ItemType == ListItemType.Item) || ((e.Item.ItemType == ListItemType.AlternatingItem))) 
    {
        XElement User = ((XElement)e.Item.DataItem).Element("Users").Element("User");

        HyperLink hlUrl = ((HyperLink)e.Item.FindControl("hlUrl"));

        hlUrl.NavigateUrl = ((XElement)e.Item.DataItem).Element("Url").Value;
        hlUrl.Text = User.Element("DisplayName").Value;
    }
}

将转发器设为:

<asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater1_OnItemDataBound">
    <HeaderTemplate>
        <b>Results</b><br />
        <br />
    </HeaderTemplate>
    <ItemTemplate>
        <asp:HyperLink ID="hlUrl" runat="server" />
    </ItemTemplate>
</asp:Repeater>

在Repeater1_OnItemDataBound上,您将能够以您想要的方式解析xml。

答案 1 :(得分:1)

如果您检查(通过在ds.ReadXml(xmlData);设置断点)数据集,您将看到UsersUser元素实际上最终作为其自己的表中的记录。记录具有id列,使您可以将行关联回包含的SearchResult行。

在您的示例中,您的绑定表[1],即SearchResult表,到转发器。您应该选择将三个表连接在一起的数据集。 LINQ在这里应该证明是有用的。

答案 2 :(得分:0)

您可以使用xml反序列化来辅助类,它复制xml节点的结构,并在转发器内为Users集合创建另一个转发器,如下所示:

<asp:Repeater runat="server" DataSource='<%# Eval("Users") %>' >...