DropDownList零代码绑定XmlDataSource完全详解

DropDownList控件在直接绑定XmlDataSource的时候会出现错误提示,这个问题把我折腾了好几宿都没睡安稳。MSDN上没有对这个问题的详细解答,CSDN上大家的解决办法也都是五花八门。终归离不开一个思路:以DataSet为跳转,先创建本地数据集从XmlDataSource里把数据取出来,再作为DropDownList的数据源进行数据绑定。这种做法不错,但是写代码的时候难免会出错,并且我对这样做的效率深表怀疑。究其根源,DropDownList不能直接绑定XmlDataSource不是VS的Bug,我也是看了国外一个大牛写的文章,才恍然大悟。

首先创建一个名为XMLDataBing的网站,在App_Data下添加新项,VS会自动添加一个数据库项。选择XML文件,如图。XML的内容就随便写一点吧:

<? xml version="1.0" encoding="utf-8"  ?>

 

< Texts >

  

   < Text >

     < Name > Text1 </ Name >

     < Id > 1 </ Id >

   </ Text >

  

   < Text >

     < Name > Text2 </ Name >

     < Id > 2 </ Id >

   </ Text >

  

   < Text >

     < Name > Text3 </ Name >

     < Id > 2 </ Id >

   </ Text >

  

</ Texts >

这是最简单也是最基本的。现在看Default.aspx的设计视图,拖一个DropDownList、一个XmlDataSource出来。一般人都会顺手写DropDownList的数据绑定:

< asp:DropDownList ID = " DropDownList1 "  runat = " server "  DataSourceID = " XmlDataSource1 "

    DataTextField = ' XPath("Name") '  DataValueField = ' XPath("Id") ' >

</ asp:DropDownList >

< asp:XmlDataSource ID = " XmlDataSource1 "  runat = " server "  DataFile = " ~/App_Data/XMLFile.xml "

    XPath = " /Texts/Text " >

</ asp:XmlDataSource >

然后编译通过,却在IE里很诧异地得到一个错误:

DataBinding:“System.Web.UI.WebControls.XmlDataSourceNodeDescriptor”不包含名为“XPath("Name")”的属性。

很醒目!错误说得很清楚,但是查MSDN死活也找不到XmlDataSourceNodeDescriptor的类定义。Google一下,查到Microsoft Online Community Support上某大牛的解释:

System.Web.UI.WebControls.XmlDataSourceNodeDescriptor  is an undocumented internal class which functions like a TypeDescriptor. It is used during data binding when the data source is XmlDataSource. Since it is an internal class, we are not having any public document on it.

大意是:System.Web.UI.WebControls.XmlDataSourceNodeDescriptor是一个未归档的内部类,它的工作原理就像TypeDescriptor。它应用在数据源是XmlDataSource的数据绑定时。由于是个内部类,我们还没有任何关于它的公开文档。

不知各位看了是个什么心情,反正我是万念俱灰了。。。。。。

MS把XmlDataSourceNodeDescriptor作为XmlDataSource数据源进行绑定的重要内部类,出很低级的Bug让DropDownList不能直接绑定XmlDataSource的可能性很小,只是我们忽略了什么重要的东西。再回头想想刚才的整个过程,表面上看不出任何问题。我们不妨重新写一个XML文件,作个小改动:

<? xml version="1.0" encoding="utf-8"  ?>

 

< Texts >

 

   < Text  Name ="Text1"  Id ="1"   />

 

   < Text  Name ="Text2"  Id ="2"   />

 

   < Text  Name ="Text3"  Id ="3"   />

 

</ Texts >

在Default.aspx上新加一个XmlDataSource,DropDownList选择数据源时会有明显的变化!数据源选择XmlDataSource2之后DataTextField和DataValueField选项会自动提示选择Name还是Id。注意,这说明DropDownList能正确读取XML文档了!

问题解决了,但原因还没找到。CSDN里有人说直接绑定就OK,显然是用第二种方法写的XML。这两种写法的区别在于

< Text  Name ="Text1"  Id ="1"   />

中,Name和Id是Text元素的属性,而

< Text >

   < Name > Text1 </ Name >

   < Id > 1 </ Id >

</ Text >

中,Name和Id并非Text元素的属性,而是一个元素节点。当数据绑定时,元素的属性会被提升为XmlDataSourceNodeDescriptor的属性,通过XmlDataSource暴露出来,但这里的元素节点却不会,导致出错。所以最简单的办法,把你的XML按第二种方法写,就可以零代码绑定了!

非得按第一种方法写,其实照样可以成功,只不过要引入一个XLST文件。不多废话,MSDN对XLST的解释如下:

XSL 转换 (XSLT) 样式表(.xslt 或 .xsl 文件)用于将源 XML 文档的内容转换为专门适合于特定用户、媒介或客户端的表现形式。

说白了,XSLT就是XML的模板。XmlDataSource会按照XSLT规定的模板读取并转换XML文档里的数据,而不考虑XML文档里规定的数据结构。在站点上点右键选添加新项,如图会有XLST文件的模板出现。恩,写一下前面例子的XSLT吧:

<? xml version="1.0" encoding="utf-8" ?>

 

< xsl:stylesheet  version ="1.0"  xmlns:xsl ="http://www.w3.org/1999/XSL/Transform" >

 

   < xsl:template  match ="Texts" >

 

     < Texts >

 

       < xsl:apply-templates  select ="Text" />

 

     </ Texts >

 

   </ xsl:template >

 

   < xsl:template  match ="Text" >

 

     < Text >

 

       < xsl:attribute  name ="Name" >

 

         < xsl:value-of  select ="Name" />

 

       </ xsl:attribute >

 

       < xsl:attribute  name ="Id" >

 

         < xsl:value-of  select ="Id" />

 

       </ xsl:attribute >

 

     </ Text >

 

   </ xsl:template >

 

</ xsl:stylesheet >

OK,别忘了在XmlDataSource1里说明使用刚才的XSLT文件

< asp:XmlDataSource ID = " XmlDataSource1 "  runat = " server "  DataFile = " ~/App_Data/XMLFile.xml "

    XPath = " /Texts/Text "  TransformFile = " ~/XSLTFile.xsl " ></ asp:XmlDataSource >

大功告成!现在得到了正确结果,大家不用再失眠了。使用XSLT还能让DataTextField和DataValueField同时绑定多个元素属性,具体方法大家可以自行Google。只有一个可考虑可忽略的问题:按照第一种写法,使用DataList或者其他某些控件时,用XPath是有效的;DropDownList为什么不能用XPath,还得多研究。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值