【问题标题】:Binding XML nodes to a Gridview C#将 XML 节点绑定到 Gridview C#
【发布时间】:2016-08-23 15:01:07
【问题描述】:

我有一个项目,其中数据存储在 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>

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

感谢任何建议。

【问题讨论】:

  • 在我试图为您找到一个好的答案时快速提问...您是否可以控制您获得的 xml 格式?另外,你必须使用 GridView 吗?
  • 嗨,James - 我可以完全控制 xml 文件的创建和格式,唯一的要求是它必须是一个将在 gridview 中显示的 xml 文档。这样做的原因是,这是一项额外的工作,是对已在使用的 Web 应用程序的扩展。

标签: c# asp.net xml


【解决方案1】:

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

理想情况下,您的 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 并不喜欢绑定到嵌套数据。肯定有办法做到这一点,但你最好只循环数据并将其打印到屏幕上。或者,您可以使用中继器控件进行调查。

试试下面的代码。我能够在一个新的 asp.net 网络表单项目中运行它。

默认.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>

默认.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(因为当前应用程序这样做是为了显示数据)。我遇到的问题是额外的工作需要显示数据,在某些情况下,对于给定的 xml 节点,这些数据具有“列表”或“多个条目”。然后将显示在 gridview 中的数据用于格式化 JSON 字符串以与远程 api 交互。到目前为止使用的方法是在页面加载时执行 xmlread,然后将该数据绑定到 gridview - 在给定属性的多个值之前效果很好!
  • 我认为我最好的选择可能是在 gridview 列中使用中继器来显示嵌套数据,所以感谢您的建议 :)
  • 我使用您喜欢的方法添加了一个新答案。让我知道它是否更接近您正在寻找的东西,或者我可以如何改进它。
【解决方案2】:

根据您的回复,我又给了它一次机会。在这里,我直接从文件中读取 xml,然后绑定到 GridView,其中嵌套了 Repeater。

您需要的唯一技巧(如下所示)是监视 GridView 上的 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>

默认.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();
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 2012-04-05
    • 1970-01-01
    • 1970-01-01
    • 2010-12-31
    • 2013-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-17
    相关资源
    最近更新 更多