将XML节点绑定到Gridview C#

时间:2016-08-23 15:01:08

标签: c# asp.net xml

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

让我们假设xml文件是书店的书籍记录(来自w3学校的例子):

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

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

感谢任何建议。

2 个答案:

答案 0 :(得分:0)

我首先要说的是有很多不同的方法可以做到这一点。如果不确切知道你要做什么,我会给你一些相当灵活的东西。容易,但也许不是最简洁或正确的#34;办法。一个更好的解决方案是涉及针对您的数据编写查询,然后显示生成的行,但这可能对您的目的而言过度。我不会在这里证明这一点。

理想情况下,您可以更好地构建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属性将会中断,但我会将此修复。希望这有帮助!

答案 1 :(得分:0)

我根据你的回答给了它另一个镜头。在这里,我直接从文件中读取xml&amp;然后使用嵌套在其中的Repeater绑定到GridView。

这里你需要的唯一技巧(如下所示)是监视GridView&amp;上的RowDataBound事件。然后为每一行去找哪些作者属于那一行。

xml文件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();
            }
        }
    }
}