我有一个项目,其中数据存储在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>
最重要的是,我想要创建的这些节点本身可能有多个属性。因此,为了保持上面这个例子,它可能是每个作者列出的出生日期和地点。
感谢任何建议。
答案 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();
}
}
}
}