【导读】本文用一个范例程序来讲解如何通过将XML文件作为数据源并将其绑定到ASP.NET DataList控件上来实现在你的web页面中显示动态的内容。
.NET Framework提供了很多方法来访问和操作数据,其中包括XML。从XML文件中读取web页面的原数据在许多方面胜过从数据库中加载内容。你可以轻松地构建XML文档并从数据库或者其他数据源中生成它们。你可以将数据分成很小的、易传输的部分,并且你还可以无限制地免费使用XML。
我将用一个范例程序来讲解如何通过将XML文件作为数据源并将其绑定到ASP.NET DataList控件上来实现在你的web页面中显示动态的内容。

图1. 在XML文件中管理页面内容
范例程序 引用了我的Getting Started专栏中的一部分索引作为数据。articles.aspx页面中用DataList控件显示文章列表。每一条包含四行内容。第一行显示了链接到一个在线文章的文章题目和Technology Toolbox。第二行包含杂志、专栏类型和出版日期。第三行是对该篇文章的简要概述,最后一行中包含了一个提供代码下载的链接。该链接返回一个带有QueryString参数的页面,使你能够对页面和文件下载的请求进行记录。
该数据代表了位于一个web服务器中的XML文档的结构(这是从范例文档中截取的小片断):
|
元素会在该文件列出的每篇文章中重复出现。
你可以将XML文件读入到一个ADO.NET 的DataSet对象中,该对象是你所指定的DataList控件的数据源。
你可以通过几种方法用.NET Framework来加载XML文件,这主要看你的数据的复杂程度以及你想如何显示它(你可以查看ADO.NET文档来了解更多这方面的内容)。最简单的方法是用DataSet对象的ReadXML方法:
Dim ds As New DataSet ds.ReadXml("c:\inetpub\demoflat.xml") |
如果你有一个XML schema(XSD)文件,那么你可以用DataSet的ReadXmlSchema方法来加载它,但ReadXml方法缺省会从输入文档中推断出一个schema。将demoflat.xml传给ReadXml方法会建立一个名为article的简单的表。是XML数据结构中最顶端的元素,就位于根元素的下面。
在DataSet中研究XML结构
你可以通过将XML数据结构显示到ASP.NET web form中的一个DataGrid控件中来轻松地对它进行研究。将一个DataGrid控件从VS.NET工具箱的web Forms栏中拖到webForm1的设计界面中。在该form的Page_Load事件中添加以下代码(双击webForm1设计界面来进入其代码部分):
Dim dsFlat As New DataSet() Dim sXmlPath As String = _ " c:\inetpub\demoflat.xml" dsFlat.ReadXml(sXmlPath) WITh DataGrid1 .DataSource = dsFlat.Tables("article") .DataBind() End WITh |
ReadXml方法用于将XML内容加载到dsFlat DataSet中。你可以在DataSet中将DataGrid的DataSource属性设置为article table,然后调用DataBind来实现连接。这就是ASP.NET中最简单的数据绑定了,你马上就会看到它的强大功能。
在运行该项目的时候,你会看到文章元素的每个参数都有一个栏目,而每篇文章都有一行。有了这个结构,你就可以将文章的题目显示为一个链接,其URL的QueryString参数来自于
webform1.aspx?id=gs0301a |
这样看起来很不错,但数据只是一个简单的行――列结构。你或许想要将该文本指定到一个链接或多个链接中,为此demohier.xml文件在元素中添加了一个
将数据绑定到层次结构中会麻烦一些。你需要修改页面以便在两个额外的DataGrid中显示demohier.xml数据。在运行该页面的时候,你会看到ADO.NET在article和codeurl表中分别建立了一个名为article_id的链接列来代表父级元素及其子元素
![]() |
|
|
接下来,将一个DataList控件从工具箱中拖到设计界面中,再将其ID属性设置为dlsArticles。设计界面中的一个灰色的矩形框代表DataList。右击矩形框,在弹出菜单中选中EdIT Template | ITem Templates。将Hyperlink控件从工具箱中拖到ITem Templates设计界面的ITem Template文本框里。将该控件的ID设为hypTITle,然后消空Text属性。
现在 ,将一个Label控件拖到项目模板中,其ID值为lblTech,然后按Enter键向下移一行。在新的一行中拖入三个Label控件:lblPub、lblType和lblDate;然后按Enter键移至第三行,拖入一个Label控件lblDescription;再按Enter键移至第四行,拖入一个hypDownload链接。右击ITem Templates的设计界面,选择End Template EdITing。
一些必带的Assembly
接下来,你必须进行一些手动操作以便改进DataList中的控件的缺省外观。点击页面设计窗口左下角的HTML标签来浏览该页面的HTML代码。将每个控件周围的
和
(段落)标签用一个简单的
(分隔符)来代替,以此缩短控件之间的垂直距离。对每个控件的样式进行格式化之后你就可以随意编辑Header、Footer和Separator模板了。
在你写好了一些代码来完成这个工作之后,你会回到该项目模板控件的数据绑定任务中。双击页面的设计界面来看看后面的代码。在articles.aspx.vb 的顶部(在类声明的上面)插入这几行代码:
Imports System.Data.OleDb Imports System.Xml Imports System.Configuration _ .ConfigurationSettings |
在"web Form Designer Generated Code" 区域上方插入这些声明:
Private mDS As New DataSet() Private msXmlPath As String |
在SE中双击并打开该项目的web.config文件(它是一个XML文件),在
这个相对路径指定了articles.xml文件将位于你项目的web根目录下的一个content目录中。
在page_load事件过程中插入以下代码以便得到该XML文件的位置并显示该页面:
msXmlPath = Server.MapPath _ (AppSettings.Get("XmlPath")) DisplayArticleData() |
接下来添加DisplayArticleData程序,它用于填充DataSet并将它和绑定DataList的DataSource属性结合起来:
Private Sub DisplayArticleData() mDS.ReadXml(msXmlPath) WITh dlsArticles .DataSource = _ mDS.Tables("article") .DataBind() End WITh End Sub |
这样就使DataSet和DataList联系起来了,其中还包含了控件,但你必须将这个DataSet中的数据和单个模板控件连接起来。返回到articles.aspx页面的设计界面中并点击HTML标签,在ITemTemplate中声明hypTITle控件,以便将标题数据元素绑定到链接文本中:
<%# DataBinder.Eval (Container.DataItem, "title") %> |
包含在<%# and %>分隔符中的字符串是一个“数据绑定表达式”。一个表达式有两种形式:一个是在执行代码时使用了DataBinder对象,另一个会返回带函数的数据(我马上就会讲到)。
在hypTITle 控件中,DataBinder对象的Eval方法用于从DataList中(一个当前容器对象)得到"tITle" DataITem。这个DataITem是从你绑定到DisplayArticleData的DataList的DataSet中得到的。还记得一篇文章中的第一个XML元素就是tITle。前面看起来复杂的表达式实际上是简单地将hyperlink控件的Text属性设置为当前记录的tITle字段的值,DataList中的一行数据会表现为表中的一行,其结果显示为一列文章的标题。
用数据绑定来节省时间
一旦了解了如何使用数据绑定,你就会发现它会为你生成一些显示数据的表,以此将你从编写大量代码的工作(就像在传统的ASP中那样)中解放出来。在ASP.NET中,你可以将更多的时间花在设计页面的外观上,而不是花在编写用于数据访问的代码上。
在运行该项目的时候你应该查看一下文章标题的列表。其他DataList的控件不会显示任何数据,因为你还没有把它们绑定到DataSource中。DataList'的Label控件是很直观的,它会显示每个绑定到DataSet的特殊字段:
<%# DataBinder.Eval (Container.DataItem,"description")%> |
hypTITle Hyperlink控件使用了第二个数据绑定的表达式,它用一个函数来返回用于navigateurl属性的数据:
navigateurl='<%# GetArticleUrl (DataBinder.Eval(Container.DataItem, "readurl")) %>' |
GetArticleUr函数从原DataSet的当前一行中取readurl值,将它作为一个参数,并返回一个带QueryString参数的相关URL,用于返回前一个页面:
Protected Function GetArticleUrl _ (ByVal LinkID As String) As String Return "articles.aspx?ID=" & LinkID End Function |
用hypDownload控件来进行数据绑定更有意思,因为它用到了输入DataSet中的多个表中的数据。GetCodeUrl和GetCodeUrlText函数分别用于返回一个URL和用于链接的文本(见列表1):
' target="_blank"> <%# GetCodeUrlText(DataBinder.Eval (Container.DataItem,"article_id"))%> |
注意要在navigateurl 参数值中使用单引号(而不是双引号)。这是很有必要的,因为双引号会在数据绑定表达式中出现。对此ASP.NET会对单引号进行正确的解释。
它会负责数据绑定任务。回到page_load事件中,检查QueryString ID参数并调用任一DisplayArticleData来显示该页面(如果没有参数的话),或者在要求文章或代码链接的情况下调用LogAndDisplayLink:
Dim sID As String = _ Request.QueryString("ID") If sID.Length > 0 Then LogAndDisplayLink(sID) Else DisplayArticleData() End If |
LogAndDisplayLink程序就象它的名字――按希望的那样记录请求,在XML链接表中根据ID查找URL,并重新定向页面请求:
'log request here ... mDS.ReadXml(msXmlPath) Dim dv As DataView = _ mDS.Tables("link").DefaultView dv.RowFilter = "id='" & LinkID & "'" Dim sURL As String = dv.ITem(0).ITem(1) Response.Redirect(sURL) |
通过DataView对象的帮助就可以实现一个链接表了。你可以设置DataView的 RowFilter属性以便从链接表中查找该项目,其ID会被传送到该页面的QueryString参数中。你可以从dv.ITem(0).ITem(1)中读取结果,其中ITem(0)代表行,而ITem(1)代表列。当用户点击其中一个链接时会打开一个新的页面并显示要求的内容。
将XML文件作为数据源是非常容易的,这使你能够选择使用一个数据库来动态地显示web内容。用ASP.NET数据绑定来结合XML数据源能使你以最少量的代码实现将数据放到web页面中。然而,当你的XML数据带有层次结构时,数据绑定任务会变得更为复杂。在有些情况下,你必须在需要使用复杂的数据和无法在web页面中显示中做出权衡
