<PersonData> <Person> <姓名>孟子E章</姓名> <身高>175</身高> <体重>72</体重> <电话>81793923</电话> </Person> <Person> <姓名>net_lover</姓名> <身高>180</身高> <体重>75</体重> <电话>81793923</电话> </Person> </PersonData>
从上面的一段XML中,我们不只可以清楚地看到每一个数据代表的是什么意义了,而且还可以晓得数据的支解位置。在我们寻常的运用中,我们获得的效果多是 数组、鸠合或记录集的表现形式,我们该怎样把它们转换成自形貌的XML花样的数据呢?从数据形式上看,XML是简朴的纯字符串的文本花样,字符串在通报时 是异常简朴、疾速而且是轻易的,数组在经由历程援用举行通报时偶然是很慢的,而且处置惩罚起来很贫苦,而鸠合和记录集都是对象,在处置惩罚时会致使计算机机能的下落, 而且这些对象都是与特定的平台相关联的,这就请求平台有内建的处置惩罚机制来处置惩罚对象的操纵。XML已是W3C的规范,是平台无关的,我们的计算机的唯一要 求就是可以处置惩罚简朴的XML字符串,即XML剖析器,它可以剖析XML字符串,可以经由历程一种接口很轻易地把数据分解成一个个自力的数据段,以便我们可以进 行接见。XML剖析器都很小,机能也很好,在每种平台上都可以找到。一旦我们接收到XML数据并把它剖析成上面的例子的款式后,我们就可以经由历程XSLT (eXstensible Stylesheet Language Transformations)把他们转换成差别的表现形式。应用XML的数据花样举行数据传输,将会使我们编写运用顺序代码的事情更简朴轻松,而且具 有优越的可伸缩性。
下面,我们就看看怎样来转换我们的数据。我们的例子是在Microsoft Windows 2000,IIS5,MSXML3和ADO2.6下编写的,样例数据采纳Microsoft SQL Server7.0自带的Northwind示例数据库。之所以采纳SQL Server7而不采纳支撑XML的SQL Server2000,是考虑到通用性的准绳,我们的目标是:处置惩罚差别范例的数据源获得的记录集,而不仅仅是象SQL Server2000那样的支撑XML输出的数据源。运用ADO,是由于它形式多样,可以处置惩罚差别范例的数据源;运用XML,是由于它可以疾速传输息争 析。但本例的处置惩罚要领也合适在任何具有Micrsoft XML剖析器,ADO2.5或以上版本的Windows,IIS,SQL Server的环境中。
为简朴起见,我们仅挑选单价小于即是20美圆,库存大于即是20,产物称号小于即是6个字符的产物:
<% Dim objRecordset Set objRecordset = Server.CreateObject("ADODB.Recordset") objRecordset.open _ "SELECT PRoductName, UnitPrice, UnitsInStock " _ & "FROM Products " _ & "WHERE UnitPrice <= 20 " _ & "AND UnitsInStock >= 20 " _ & "AND LEN(ProductName) <= 6 " _ & "ORDER BY ProductName", _ "Provider=SQLOLEDB;" _ & "Data Source=SomeSQLServer;" _ & "Initial Catalog=Northwind;" _ & "User ID=MyUserName;" _ & "PassWord=MyPassword;" %>
如今,我们就用3种体式格局把我们获得的记录集转换成XML花样。
起首,我们可以遍历全部记录集,采纳XML DOM(Document Object Model),竖立XML节点树:
<% Dim objXMLDOM, objRootNode, objNode Set objXMLDOM = Server.CreateObject("MSXML2.DOMDocument") Set objRootNode = objXMLDOM.createElement("xml") objXMLDOM.documentElement = objRootNode Do While NOT objRecordset.EOF Set objRowNode = objXMLDOM.createElement("row") Set objNode = objXMLDOM.createElement("ProductName") objNode.text = objRecordset.Fields.Item("ProductName").Value objRowNode.appendChild(objNode) Set objNode = objXMLDOM.createElement("UnitPrice") objNode.text = objRecordset.Fields.Item("UnitPrice").Value objRowNode.appendChild(objNode) Set objNode = objXMLDOM.createElement("UnitsInStock") objNode.text = objRecordset.Fields.Item("UnitsInStock").Value objRowNode.appendChild(objNode) objRootNode.appendChild(objRowNode) objRecordset.MoveNext Loop Set objNode = Nothing Set objRowNode = Nothing Set objRootNode = Nothing Set objRecordset = Nothing %>
如今,我们就获得了一个XML DOM对象。这类要领关于记录集很大时机能并不抱负,由于体系内存中要同时保留ADO记录集对象和XML DOM对象。
第二个方法,遍历记录集,直接生成XML字符串自身:
<% Dim strXML strXML = "<xml>" objRecordset.MoveFirst Do While NOT objRecordset.EOF strXML = strXML & "<row>" strXML = strXML & "<ProductName>" _ & objRecordset.Fields.Item("ProductName").Value _ & "</ProductName>" strXML = strXML & "<UnitPrice>" _ & objRecordset.Fields.Item("UnitPrice").Value _ & "</UnitPrice>" strXML = strXML & "<UnitsInStock>" _ & objRecordset.Fields.Item("UnitsInStock").Value _ & "</UnitsInStock>" strXML = strXML & "</row>" objRecordset.MoveNext Loop strXML = strXML & "</xml>" Set objRecordset = Nothing %>
然则,以上两种要领最大的缺点是不可以重用代码,我们把节点的名字都写死了,假如我们举行差别字段的查询,我们还必须手动变动我们的代码,以满足差别节点的须要。我们下面的要领将变得越发通用。
第三种要领:可重用的要领。
<% Dim strXML strXML = "<xml>" objRecordset.MoveFirst Do While NOT objRecordset.EOF strXML = strXML & "<row>" For Each varItem In objRecordset.Fields strXML = strXML _ & "<" & varItem.name & ">" _ & varItem.value _ & "</" & varItem.name & ">" Next strXML = strXML & "</row>" objRecordset.MoveNext Loop strXML = strXML & "</xml>" Set objRecordset = Nothing %>
一个更有效的要领,我们可以直接应用记录集内建的save要领,它可以自动地把记录集的内容转换成XML花样,我们挪用save要领后,我们就可以马上释 放内存中的记录集对象实例。 save要领有两个参数:一个是XML要保留的处所,一个是指导符,标明数据以何种花样保留。我们可以把数据保留成XML DOM对象(ADO STREAM对象),也可以直接保留成asp RESPONSE对象,为通用起见,我们保留成XML DOM,第二个参数用adPersistXML ADO常量。要领以下:
<% Const adPersistXML = 1 Dim objXMLDOM Set objXMLDOM = Server.CreateObject("MSXML2.DOMDocument.3.0") objRecordset.save objXMLDOM, adPersistXML Set objRecordset = Nothing %>
这类要领方便快捷,而且不轻易失足,对差别的查询,也不必手动变动节点名字。然则,这类要领发生的XML不够简约,看看它发生的效果:
<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema"> <s:Schema id="RowsetSchema"> <s:ElementType name="row" content="eltOnly" rs:CommandTimeout="30"> <s:AttributeType name="ProductName" rs:number="1" rs:writeunknown="true"> <s:datatype dt:type="string" dt:maxLength="40" rs:maybenull="false"/> </s:AttributeType> <s:AttributeType name="UnitPrice" rs:number="2" rs:nullable="true" rs:writeunknown="true"> <s:datatype dt:type="number" rs:dbtype="currency" dt:maxLength="8" rs:precision="19" rs:fixedlength="true"/> </s:AttributeType> <s:AttributeType name="UnitsInStock" rs:number="3" rs:nullable="true" rs:writeunknown="true"> <s:datatype dt:type="i2" dt:maxLength="2" rs:precision="5" rs:fixedlength="true"/> </s:AttributeType> <s:extends type="rs:rowbase"/> </s:ElementType> </s:Schema> <rs:data> <z:row ProductName="Chai" UnitPrice="18" UnitsInStock="39"/> <z:row ProductName="Konbu" UnitPrice="6" UnitsInStock="24"/> <z:row ProductName="Tofu" UnitPrice="23.25" UnitsInStock="35"/> </rs:data> </xml>
ADO 自动发生的XML包含了schema信息,它形貌这个XML里许可有什么节点和属性以及采纳何种数据范例,而且数据节点也增加了称号空间。schema信 息在须要数据考证的处所或举行更庞杂的处置惩罚也许很有效,然则,大多数情况下,我们运用的是瘦客户机,我们不须要schema信息。我们可以应用XSLT来 星散出我们想要的信息,去掉过剩的信息。因而,我们编写下面的“ DataCleaner.xsl”:
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema"> <xsl:output omit-xml-declaration="yes"/> <xsl:template match="/"> <xsl:element name="xml"> <xsl:for-each select="/xml/rs:data/z:row"> <xsl:element name="row"> <xsl:for-each select="@*"> <xsl:element name="{name()}"> <xsl:value-of select="."/> </xsl:element> </xsl:for-each> </xsl:element> </xsl:for-each> </xsl:element> </xsl:template> </xsl:stylesheet>
这个XSLT具有可重用的特征,关于差别的查询效果都实用,下面就是怎样运用这个XSLT的例子:
<% Dim strCleanXML, objXMLDOM_XSLT Set objXMLDOM_XSLT = CreateObject("MSXML2.DOMDocument") objXMLDOM_XSLT.load(Server.MapPath("DataCleaner.xsl")) strCleanXML = objXMLDOM.transformNode(objXMLDOM_XSLT) Set objXMLDOM = Nothing Set objXMLDOM_XSLT = Nothing %>
经由上面的处置惩罚今后,strClaenXML就是我们所想要的XML字符串了。
<xml> <row> <ProductName>Chai</ProductName> <UnitPrice>18</UnitPrice> <UnitsInStock>39</UnitsInStock> </row> <row> <ProductName>Konbu</ProductName> <UnitPrice>6</UnitPrice> <UnitsInStock>24</UnitsInStock> </row> </xml>
上面这类花样的XML字符串是我们常常见到的节点集的款式,假如您不想把字段处置惩罚成节点,而把它处置惩罚成属性节点,那末我们只需对DataCleaber.xsl略加修改即可:
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema"> <xsl:output omit-xml-declaration="yes"/> <xsl:template match="/"> <xsl:element name="xml"> <xsl:for-each select="/xml/rs:data/z:row"> <xsl:element name="row"> <xsl:for-each select="@*"> <xsl:attribute name="{name()}"> <xsl:value-of select="."/> </xsl:attribute> </xsl:for-each> </xsl:element> </xsl:for-each> </xsl:element> </xsl:template> </xsl:stylesheet>
以下是采纳了新款式的效果,它比用节点示意字段的长度要短的多了。传输起来速率会更快:
<xml> <row ProductName="Chai" UnitPrice="18" UnitsInStock="39"/> <row ProductName="Konbu" UnitPrice="6" UnitsInStock="24"/> </xml>
到此为止,我们引见了从ADO 记录集获得XML花样数据的几种方法,也获得了最简化的字符串。然则有几个题目你依然须要注重,有些字段值另有XML里不支撑的字符,比方:"'< >&,象P&G宝洁公司的称号,Chef Anton's Gumbo Mix产物名字等,在做转换时要举行编码处置惩罚。在Microsoft ADO 2.6的SDK里有运用save要领时要注重的题目:1,save要领只对open Recordset起作用;2,不支撑带有adVariant,adIDispatch,adIUnknown范例的字段的记录集的savw;3,当保留 分级的记录集( data shapes)有两个限定:不能保留参数化和含有未处理的更新的记录集。
为了更进一步进步机能,你可以把转换事情放 到COM/COM+组件中, ASP代码只举行数据的终究表现即可。把营业层、数据层和表现层离开,ASP只须要挪用数据组件,数据组件挪用数据库的存储历程,把效果转换成XML,最 后只把简朴的XML字符环串回到ASP顺序里,ASP就可以用XSLT把XML举行转换,把效果送到浏览器。
以上就是应用XSLT把ADO记录集转换成XML的内容,更多相关内容请关注ki4网(www.ki4.cn)!