将XML节点绑定到Gridview c#
本文关键字:Gridview 绑定 XML 节点 | 更新日期: 2023-09-27 18:03:33
我有一个项目,其中数据存储在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();
}
}
}
}