将XML节点绑定到Gridview c#



我有一个项目,其中数据存储在xml文档中,然后在asp.net gridview中显示。每一列表示文件中的一个不同节点。然而,我已经达到了一种情况,我有多个节点,所以我需要一些关于如何实现这一点的建议。

让我们假设xml文件是一个书店的图书记录(以w3 schools为例):

<book category="web">
<title lang="en">XQuery Kick Start</title>
<author>James McGovern</author>
<author>Per Bothner</author>
<author>Kurt Cagle</author>
<author>James Linn</author>
<author>Vaidyanathan Nagarajan</author>
<year>2003</year>
<price>49.99</price>

正如你在这个例子中看到的,有很多作者,所以如果我有多个节点(在这个例子中是作者)我怎么能把它们加载到gridview?是否建议将每个节点命名为作者1、作者2、作者3等?或者是否可以创建一个子节点,即

    <author>
         <name1> </name1>
         <name2> </name2>
         <name3> </name3>
    </author>

最后重要的一点是,我想要创建的这些节点本身可能有几个属性。因此,为了保持上面的例子,它可能是列出的每个作者的出生日期和地点。

我首先要说的是有很多不同的方法可以做到这一点。在不知道你想做什么的情况下,我会给你一些相当灵活的东西& &;简单,但也许不是最简洁或"正确"的方式。更好的解决方案是针对数据编写查询,然后显示结果行,但对于您的目的来说,这可能有些多余。我不会在这里演示。

理想情况下,你应该像下面这样构造你的xml:

<books>
    <book category='web'>
        <title lang='en'>XQuery Kick Start</title>
        <authors>
            <author>Vaidyanathan Nagarajan</author>
            <author>thomas waterloo</author>
            <author>malinda gatesauthor>
            <author>rusty weatherford</author>
        <authors>
        <year>2003</year>
        <price>49.99</price>
    </book>
</books>

其次,GridView并不喜欢绑定到嵌套数据。肯定有一种方法可以做到这一点,但您最好只是循环遍历数据并将其打印到屏幕上。或者,您可以研究使用Repeater控件。

试试下面的代码。我能够得到这个运行在一个新的asp.net web表单项目。

default . aspx:

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
<%@ Import Namespace="System.Xml" %>
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
    <table>
    <% foreach ( XmlNode book in myNodes) { %>
            <tr>
            <% foreach ( XmlNode childElement in book ) {
                   string title = null;
                   string year = null;
                   string price = null;
                   List<string> authors = new List<string>();
                   switch (childElement.Name)
                   {
                       case "title":
                           title = childElement.InnerText.ToString();
                           break;
                       case "year":
                           year = childElement.InnerText.ToString();
                           break;
                       case "price":
                           price = childElement.InnerText.ToString();
                           break;
                       case "authors":
                           foreach (XmlNode grandChildElement in childElement)
                           {
                               authors.Add(grandChildElement.InnerText);
                           }
                           break;
                   }%>
                    <td><label><%= title %></label></td>
                    <td><label><%= year %></label></td>
                    <td><label><%= price %></label></td>
                    <td>
                        <%foreach( string author in authors ){ %>
                            <label> <%= author %></label><br />
                        <% } %>
                    </td>
            <% } %>
            </tr>
    <% } %>
    </table>
</asp:Content>

Default.aspx.cs:

using System;
using System.Data;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
namespace WebApplication1
{
    public partial class _Default : Page
    {
        protected XmlNodeList myNodes = null;
        protected void Page_Load(object sender, EventArgs e)
        {
            string booksXml = @"<books>
                <book category='web'>
                    <title>Columbus Sailed the Ocean Blue</title>
                    <year>1492</year>
                    <price>6 gold doubloons</price>
                    <authors>
                        <author>Vaidyanathan Nagarajan</author>
                        <author>john doe</author>
                        <author>jane doe</author>
                    </authors>
                </book>
                <book category='web'>
                    <title>Best Book Ever</title>
                    <year>1776</year>
                    <price>23.55</price>
                    <authors>
                        <author>Robert Frost</author>
                    </authors>
                </book>
                <book category='web'>
                    <title>Hello World!</title>
                    <year>20013</year>
                    <price>49.99</price>
                </book>
                <book category='web'>
                    <title>1234</title>
                    <year>1999</year>
                    <price>69.99</price>
                    <authors>
                        <author>Carmen SanDiego</author>
                        <author>Roger Rabbit</author>
                    </authors>
                </book>
            </books>";
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(booksXml);
            //doc.ChildNodes[0] is the entire books element and al of its children
            //doing .ChildNodes again gives you all of the book elements
            this.myNodes = doc.ChildNodes[0].ChildNodes;
        }
    }
}

如果节点结构变得更复杂,使用innertext属性将会失效,但我将把这个问题留给您解决。希望这对你有帮助!

根据你的回答,我再试一次。这里我直接从文件中读取xml &然后绑定到GridView,并在其中嵌套一个Repeater。

你在这里需要的唯一技巧(下面演示)是监视GridView上的RowDataBound事件。然后,对于每一行,查找哪些作者属于该行。

books.xml文件

<books>
    <book category='web'>
        <title>Columbus Sailed the Ocean Blue</title>
        <year>1492</year>
        <price>6 gold doubloons</price>
        <author>Vaidyanathan Nagarajan</author>
        <author>john doe</author>
        <author>jane doe</author>
    </book>
    <book category='web'>
        <title>Best Book Ever</title>
        <year>1776</year>
        <price>23.55</price>
        <author>Robert Frost</author>
    </book>
    <book category='web'>
        <title>Hello World!</title>
        <year>20013</year>
        <price>49.99</price>
    </book>
    <book category='web'>
        <title>1234</title>
        <year>1999</year>
        <price>69.99</price>
        <author>Carmen SanDiego</author>
        <author>Roger Rabbit</author>
    </book>
</books>

default . aspx

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
<%@ Import Namespace="System.Xml" %>

<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
    <asp:GridView ID="myGridView" runat="server" AutoGenerateColumns="false" OnRowDataBound="myGridView_RowDataBound" >
         <Columns>
             <asp:TemplateField>
                 <ItemTemplate>
                     <label> Title: <%# Eval("title")%></label>
                     <label> Year:<%# Eval("year")%></label>
                     <label> Price:<%# Eval("price")%></label>
                     <asp:Repeater ID="myRepeater" runat="server">
                          <HeaderTemplate>
                            <table>
                                <thead>Authors: </thead>
                        </HeaderTemplate>
                        <ItemTemplate>
                            <tr>
                                <td>
                                    <asp:Label ID="myLabel" runat="server"><%# Eval("author_Text")%></asp:Label>
                                </td>
                            </tr>
                        </ItemTemplate>
                        <FooterTemplate>
                            </table>
                            <br />
                        </FooterTemplate>
                     </asp:Repeater>
                 </ItemTemplate>
             </asp:TemplateField>
         </Columns>
    </asp:GridView>
</asp:Content>

Default.aspx.cs

using System;
using System.Data;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
namespace WebApplication1
{
    public partial class _Default : Page
    {
        DataTableCollection tables = null;
        protected void Page_Load(object sender, EventArgs e)
        {
            XmlDocument doc = new XmlDocument();
            DataSet ds = new DataSet();
            ds.ReadXml("C:\dev\books.xml");
            //ds.Tables[0] is the books table
            //ds.Tables[1] is the authors table
            // When reading xml into a DataSet object, the data is normalized (think SQL-like)
            myGridView.DataSource = ds.Tables[0];
            tables = ds.Tables;
            myGridView.DataBind();
        }
        protected void myGridView_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                Repeater repeater = (Repeater)e.Row.FindControl("myRepeater");
                // Because our data is now in tables, we need to join the tables based on the book_Id identifier
                // The columns named book_Id in table 0 and table 1 were both created for us automatically to link up the data
                // when we read the xml into the DataSet object.
                var authors = tables[1].AsEnumerable().Where(x => x["book_Id"] as int? == e.Row.DataItemIndex).AsDataView();
                repeater.DataSource = authors;
                repeater.DataBind();
            }
        }
    }
}

最新更新