记得在《透视和调整你的企业和商务系统》一文中,我们讨论了有关组件、SOAP、WebService的一些问题,特别对于这样的一些问题:
如何生成一个构造一个简单的三层结构(Window DNA)
如何将现有的组件暴露出来,成为一个WebService
如何使用MS SOAP Toolkit来生成Client消费WebService
如何在dotNET中调用SOAP Toolkit生成的WebService
如何处理和传输ADODB.Recordset类型的数据,实现自己的CTM。
如何将目前的组件用ASP.NET封装成WebService
进行了一些讨论和实验,在讨论到用ASP.NET封装我们的组件成WebService,然后使用MS SOAP Toolkit消费WebService时,我曾跳过了一个问题,那就是如何接收WebService传输过来的成组数据。
记得代码是这样的:
Dim RetXML as Object
Dim SoapClient As MSSOAPLib.SoapClient
Set SoapClient = New MSSOAPLib.SoapClient
Call SoapClient.mssoapinit("http://Dereksvr/Authors/Authors.asmx?WSDL")
Set RetXML = SoapClient.GetAuthors()
GetAuthors()返回的是一个DataSet类型,在开始生成WebService时我们是这样封装的:
<WebMethod()> Public Function GetAuthors() As DataSet
Dim obj As bus_Authors.Authors
Dim rst As ADODB.Recordset
Dim myDataAdapter As OleDb.OleDbDataAdapter
Dim retDataset As DataSet
obj = New bus_Authors.Authors()
rst = New ADODB.Recordset()
myDataAdapter = New OleDb.OleDbDataAdapter()
retDataset = New DataSet()
rst = obj.GetAuthors()
myDataAdapter.Fill(retDataset, rst, "GetAuthors")
GetAuthors = retDataset
End Function
而对于VB来说RetXML将是不可以认识和直接使用的,好在Dataset是基于XML的,事实上它是有规律的,我们可以通过直接访问.asmx文件(http://Dereksvr/Authors/Authors.asmx)来在网页上调用这个WebService 的GetAuthors(),在IE中我们可以看到这个Dataset的结构,这样我们就可以找出规律,来使用这个Dataset中的数据。
根据上面的情况我写了一个函数可以将Dataset转换成ADODB.Recordset
Public Function ConvDatasetToRecordset(ByVal voNL As IXMLDOMNodeList, ByVal vsTableName As String) As ADODB.Recordset
Dim iXMLTableNode As IXMLDOMNode
Dim iXMLRecordNode As IXMLDOMNode
Dim iXMLFieldNode As IXMLDOMNode
Dim iXMLNodeList As IXMLDOMNodeList
Dim retRS As ADODB.Recordset
Dim sXPath As String
On Error GoTo ErrHandle
' Create Recordset using the xsd schema
sXPath = "//xsd:element[@name=""" & vsTableName & """]/xsd:complexType/xsd:sequence"
Set iXMLTableNode = voNL.Item(1).selectSingleNode(sXPath)
Set retRS = New ADODB.Recordset
For Each iXMLFieldNode In iXMLTableNode.childNodes
If Not iXMLFieldNode.Attributes Is Nothing Then
Call retRS.Fields.Append(iXMLFieldNode.Attributes(0).Text, GetDataType(iXMLFieldNode.Attributes(1).Text), 512)
End If
Next
' Add the data to the Recordset
sXPath = "//" & vsTableName
Set iXMLNodeList = voNL.Item(3).selectNodes(sXPath)
Call retRS.Open
For Each iXMLRecordNode In iXMLNodeList
Call retRS.AddNew
For Each iXMLFieldNode In iXMLRecordNode.childNodes
If Len(iXMLFieldNode.baseName) > 0 Then
retRS.Fields(iXMLFieldNode.baseName) = iXMLFieldNode.Text
End If
Next
Next
If Not (retRS.BOF And retRS.EOF) Then Call retRS.MoveFirst
Set ConvDatasetToRecordset = retRS
ErrExit:
Exit Function
ErrHandle:
Set ConvDatasetToRecordset = Nothing
Resume ErrExit
End Function
Private Function GetDataType(ByVal vsType As String) As ADODB.DataTypeEnum
' Convert the XS