第14章ASP.NETXML和WebService在上一章中讲到的Web.config配置文件就是基于XML文件格式的,XML(ExtensibleMarkupLanguage,可扩展标记语句)是一种描述数据和数据结构的语言,XML文本可以保存在任何存储文本中,这就让XML具有了可扩展性、跨平台型以及传输与存储方面的优点。14.1XML简介标记语言(MarkupLanguage)特指一系列约定好的标记来对电子文档进行标记,以实现对电子文档的语义、结构以及格式的定义。在ASP.NET开发中,最常用的标记语言就是HTML,HTML标记语言定义了HTML文档的语义、结构以及格式,以便在不同的浏览器中所呈现的内容是一致的。XML标记语言与SGML和HTML都属于标记语言,标记语言的发展如图14-1所示。图14-1标记语言的发展史为了更加方便的适应互联网的需求,1996年开始创建XML标记语言。XML标记语言不仅具备了SGML标记语言强大的扩展性,同样也具备HTML标记语言的易用性。不仅如此,ASP.NET还将XML作为应用程序数据存储和传输的重要方法。在当今互联网中,Web应用已经成为一种分布式组件技术。传统的Web应用技术解决的问题是如何让人使用Web提供的应用,而当今的Web应用技术是要解决如何让应用程序使用Web应用。由于Web应用能够跨平台、跨语言的为应用程序提供服务,所以Web应用和XML应用的前景是非常广阔的。367注意:这里所说的Web应用的跨平台是针对浏览器而言,Windows能够浏览一个Web应用,而Linux同样可以浏览一个Web应用。14.2读写XMLXML和HTML都是基于SGML(StandardGeneralizedMarkupLanguage,标准通用标记语言)的,但是XML和HTML却有着很大的区别,这些区别不仅仅在于格式上的区别,还在于使用性、可扩展性等等。14.2.1XML与HTMLXML标记语言和HTML标记语言有着极大的不同,在应用程序开发中,XML标记语言能够适应于大部分的应用程序环境和开发需求。这些需求是HTML标记语言无法做到的,XML标记语言和HTML标记语言的具体区别如下所示。HTML标记是固定的,并且是没有层次的,在HTML文档中,用户无法自行创建标签,例如book这样的标签浏览器很可能解析不了,HTML中标记的作用是描述数据的显示方式,这种方式只能交付给浏览器进行处理,而HTML文档中的标记都是独立存在的,没有层次。XML的标记不是固定的且是有层次的,在XML文档中,用户可以自行创建标签,例如day这样的标签,XML标记不能够描述网页的外观和内容,XML只能够描述内容的数据结构和层次,在浏览器中浏览XML文档,也可以发现XML标记是有层次的。在VisualStudio2008中,.NETFramework提供了System.XML命名空间,该命名空间提供了一组可扩展类使得开发人员能够轻松的读、写、以及编辑XML文本。14.2.2创建XML文档使用VisualStudio2008能够创建XML文档,创建和使用XML文档无需XML语法分析器来专门负责分析语法,在.NETFramework中已经集成了可扩展类。右击现有项,单击【添加新项】选项,选择XML文件,如图14-2所示。图14-2创建XML文档368创建完成后,就需要向XML文档中编写XML标记,以下是一个完整的XML文档示例。?xmlversion=1.0encoding=utf-8?RootShopInformationarea=AsiaShopplace=WuhanName武汉电脑城/NamePhone123456789/PhoneSellerJ.Dan/SellerSellerBillGates/Seller/ShopShopplace=ShangHaiName武汉电脑城/NamePhone123456789/PhoneSellerBillGates/Seller/Shop/ShopInformationShopInformationarea=USAShopplace=SNamePCSTORE/NamePhone123456789/PhoneSellerJ.Dan/SellerSellerBillGates/Seller/ShopShopplace=S.KNameWindowsMobileStore/NamePhone123456789/PhoneSellerBillGates/Seller/Shop/ShopInformation/Root上述XML文档使用了自定义标记对商城进行了描述,包括商城所在地、商城名称、电话号码以及负责人等。编写XML文档时,开发人员能够自定义标签进行文档描述,但是在XML文档的头部必须进行XML文档声明,示例代码如下所示。?xmlversion=1.0encoding=utf-8?上述代码在XML文档头部进行了声明,表示该文档是一个XML文档,并且说明该文档的版本为1.0的XML文档,该文档还可以包含一个encoding属性,指明文档中的编码类型。声明该文档是一个XML文档后,则需要在XML文档中编写根标记,这个标记可以是开发人员自定义标记名称,在这里被命名为Root,示例代码如下。Root!--根标记内的所有内容--/Root上述代码创建了一个根标记,在这里命名为Root。在XML文档中,所有的标记都应该被包含在一个根标记中,这样不仅方便描述也方便查阅。XML文档中的根标记不能够重复使用,如果重复使用则会提示异常。在根标记内,应该编写需要描述的信息的标记。在这里,描述一个商城需要的一些属性,包括商城所在的州、所在地以及商城的主营类型等,通过XML标记语言可以自行创建标记来描述,示例代码如下所示。369ShopInformationarea=USA//地区描述Shopplace=S//位置描述NamePCSTORE/Name//商城名称Phone123456789/Phone//商城电话SellerJ.Dan/Seller//商城销售人员SellerBillGates/Seller/ShopShopplace=S.KNameWindowsMobileStore/NamePhone123456789/PhoneSellerBillGates/Seller/Shop/ShopInformation上述代码对商城的信息进行了描述,这些标签的意义如下所示:ShopInformation:商城信息,包括area属性来描述所在州或板块,这里说明了是在USA地区。Shop:商城在该板块的所在州、省市等信息。Name:商城的名称。Phone:商城的联系电话。Seller:商城的销售人员。这些标签都是用户自定义的,XML文档允许开发人员自定义标签并,另外,XML文档也不局限所要描述的对象格式。例如当上述代码也可以编写另外一种样式时,同样能够被XML所识别,示例代码如下所示。ShopInformationAreaname=Usa//另一种地区表示方式ShopNamePCSTORE/NamePhone123456789/PhoneSellerJ.Dan/SellerSellerBillGates/SellerPlaceS.K/Place//地区直接放在描述中/ShopShopNameWindowsMobileStore/NamePhone123456789/PhoneSellerBillGates/SellerPlaceS/Place/Shop/Area/ShopInformation技巧:良好的缩进能够让XML文档更加方便阅读,同时XML文档是大小写敏感的,对于XML标记,标记头和标记尾的大小写规则必须匹配。14.2.3XML控件在ASP.NET中提供了针对XML读写的控件XML控件,XML控件可以很好的解决XML文档的显示问题,如果需要浏览XML文档的数据,则只需要编写XML控件中的DocumentSource属性即可,示370例代码如下所示。bodyformid=form1runat=serverdivasp:XmlID=xml1runat=serverDocumentSource=~/XMLFile1.xml/asp:Xml//使用XML控件/div/form/body运行后如图14-3所示。图14-3XML控件运行后会发现XML文档的内容都显示出来了,但是却没有层次感,因为XML控件并没有把记录分开,而是连续的呈现XML文档的内容。如果需要按照规范或开发人员的意愿呈现给浏览器,则必须使用XSL样式表。14.2.4XML文件读取类(XmlTextReader)XmlTextReader类属于System.Xml命名空间,XmlTextReader类提供对XML数据的快速、单项、无缓冲的数据读取功能,因为XmlTextReader类是基于流的,所以使用XmlTextReader类读取XML内容只能够从前向后读取,而不能逆向读取。因为XmlTextReader类的流形式,节约了读取XML文档的时间,也大量的节约了读取XML所需花费的内存空间,当需要读取XML节点时,只需要使用XmlTextReader类的Read()方法即可,示例代码如下所示。XmlTextReaderrd=newXmlTextReader(Server.MapPath(XMLFile1.xml));//构造函数while(rd.Read())//遍历节点{Response.Write(NodeTypeis:+rd.NodeType+ br/);//输出NodeResponse.Write(Nameis:+rd.Name+ br/);//输出NameResponse.Write(Valueis:+rd.Value+ br/);//输出ValueResponse.Write(hr/);}上述代码使用XmlTextReader类的构造函数创建了XmlTextReader对象,并通过使用XmlTextReader类的Read()方法进行XmlTextReader对象的遍历。遍历XML文档后,需要使用Close方法进行XmlTextReader对象的关闭操作,这一点是非常重要的,如果不使用XmlTextReader类的Close方法,则相应的XML文件正在被进程使用,只有使用了Close方法才能将相应的文件关闭掉。示例代码如下371所示。rd.Close();//关闭ReaderXmlTextReader类遍历XML文件运行结果如图14-4所示。图14-4XmlTextReader类遍历XML文件在使用XmlTextReader类读取XML文件中相应的节点时,XmlTextReader类的NodeType会检查节点的类型,而XmlTextReader类的Name和Value会分别检查节点的名称和值,相应的XML代码如下所示。Shopplace=WuhanName武汉电脑城/NamePhone123456789/PhoneSellerJ.Dan/SellerSellerBillGates/Seller/Shop上述代码中,使用XmlTextReader类进行读取,则Shop节点的NodeType为Element,Name的值为Shop,Value的值为空。XML文档中不止以上几种节点类型,XmlNodeType也包括其他节点类型,这些类型如