我调用一个Web Service返回一个XML格式的文件,格式如下 <?xml version="1.0" encoding="utf-8" ?>
- <DataSet xmlns="http://tempuri.org/CHTWebservice1/Service1">
- <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
- <xs:element name="NewDataSet" msdata:IsDataSet="true">
- <xs:complexType>
- <xs:choice maxOccurs="unbounded">
- <xs:element name="FailureTable">
- <xs:complexType>
- <xs:sequence>
<xs:element name="SN" type="xs:string" minOccurs="0" />
<xs:element name="SO" type="xs:string" minOccurs="0" />
<xs:element name="FAIL_CODE" type="xs:string" minOccurs="0" />
<xs:element name="DESCRIPTION" type="xs:string" minOccurs="0" />
<xs:element name="DATETIME" type="xs:dateTime" minOccurs="0" />
<xs:element name="STATION" type="xs:string" minOccurs="0" />
<xs:element name="ACTOR" type="xs:string" minOccurs="0" />
<xs:element name="STATUS" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
- <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
- <NewDataSet xmlns="">
- <FailureTable diffgr:id="FailureTable1" msdata:rowOrder="0">
<SN>TEST006</SN>
<SO>TEST_SO_01</SO>
<FAIL_CODE>LOSESIGNAL</FAIL_CODE>
<DESCRIPTION>test failure comment of Lose signal</DESCRIPTION>
<DATETIME>2006-02-07T17:49:29.0000000+07:00</DATETIME>
<STATION>200</STATION>
<ACTOR>4224</ACTOR>
<STATUS>CLOSE</STATUS>
</FailureTable>
- <FailureTable diffgr:id="FailureTable2" msdata:rowOrder="1">
<SN>DEV1000</SN>
<SO>TEST_SO</SO>
<FAIL_CODE>NOPOWER</FAIL_CODE>
<DESCRIPTION>desc on tracking table</DESCRIPTION>
<DATETIME>2006-03-12T21:58:26.0000000+07:00</DATETIME>
<STATION>200</STATION>
<ACTOR>1234</ACTOR>
<STATUS>OPEN</STATUS>
</FailureTable>
- <FailureTable diffgr:id="FailureTable3" msdata:rowOrder="2">
<SN>DEV1000</SN>
<SO>TEST_SO</SO>
<FAIL_CODE>FREQLOW</FAIL_CODE>
<DESCRIPTION>desc on tracking table</DESCRIPTION>
<DATETIME>2006-03-12T21:58:26.0000000+07:00</DATETIME>
<STATION>200</STATION>
<ACTOR>1234</ACTOR>
<STATUS>OPEN</STATUS>
</FailureTable>
我该如何读取他,并且将他保存在recordset里面这个在web service 里返回的是dataset 的,程序自转转换后就成为上面这种格式啦..如果在VB.NET里面很方便的可以....在VB里不会,可否路过的朋友有知道的告之一声,不胜感激,我的一百分都给你,说话算话.
- <DataSet xmlns="http://tempuri.org/CHTWebservice1/Service1">
- <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
- <xs:element name="NewDataSet" msdata:IsDataSet="true">
- <xs:complexType>
- <xs:choice maxOccurs="unbounded">
- <xs:element name="FailureTable">
- <xs:complexType>
- <xs:sequence>
<xs:element name="SN" type="xs:string" minOccurs="0" />
<xs:element name="SO" type="xs:string" minOccurs="0" />
<xs:element name="FAIL_CODE" type="xs:string" minOccurs="0" />
<xs:element name="DESCRIPTION" type="xs:string" minOccurs="0" />
<xs:element name="DATETIME" type="xs:dateTime" minOccurs="0" />
<xs:element name="STATION" type="xs:string" minOccurs="0" />
<xs:element name="ACTOR" type="xs:string" minOccurs="0" />
<xs:element name="STATUS" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
- <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
- <NewDataSet xmlns="">
- <FailureTable diffgr:id="FailureTable1" msdata:rowOrder="0">
<SN>TEST006</SN>
<SO>TEST_SO_01</SO>
<FAIL_CODE>LOSESIGNAL</FAIL_CODE>
<DESCRIPTION>test failure comment of Lose signal</DESCRIPTION>
<DATETIME>2006-02-07T17:49:29.0000000+07:00</DATETIME>
<STATION>200</STATION>
<ACTOR>4224</ACTOR>
<STATUS>CLOSE</STATUS>
</FailureTable>
- <FailureTable diffgr:id="FailureTable2" msdata:rowOrder="1">
<SN>DEV1000</SN>
<SO>TEST_SO</SO>
<FAIL_CODE>NOPOWER</FAIL_CODE>
<DESCRIPTION>desc on tracking table</DESCRIPTION>
<DATETIME>2006-03-12T21:58:26.0000000+07:00</DATETIME>
<STATION>200</STATION>
<ACTOR>1234</ACTOR>
<STATUS>OPEN</STATUS>
</FailureTable>
- <FailureTable diffgr:id="FailureTable3" msdata:rowOrder="2">
<SN>DEV1000</SN>
<SO>TEST_SO</SO>
<FAIL_CODE>FREQLOW</FAIL_CODE>
<DESCRIPTION>desc on tracking table</DESCRIPTION>
<DATETIME>2006-03-12T21:58:26.0000000+07:00</DATETIME>
<STATION>200</STATION>
<ACTOR>1234</ACTOR>
<STATUS>OPEN</STATUS>
</FailureTable>
我该如何读取他,并且将他保存在recordset里面这个在web service 里返回的是dataset 的,程序自转转换后就成为上面这种格式啦..如果在VB.NET里面很方便的可以....在VB里不会,可否路过的朋友有知道的告之一声,不胜感激,我的一百分都给你,说话算话.
格式与Recordset产生的xml不一样的,
只有用Xsl和DOM来转化了
Dim psnodeName As String
Set doc = CreateObject("Microsoft.XMLDOM")
doc.async = False
doc.Load ("pcClass.wsm_getComponent('')")Set Root = doc.documentElement '在这里会提示有错误
Set nodelis = Root.childNodes
nodecount = nodelis.Length
For i = 1 To nodecount
Set node = nodelis.NextNode()
Dim objRS As RecordsetIf objXML.loadXML(strXML) Then
Set objRS = New Recordset
objRS.Open objXML
End if ===============
楼主应该可以用
MSXML.XMLHTTPRequest 来取得xml串,楼主应该有这方面的代码了吧,我就不贴了
http://www.chenoe.com/blog/blogview.asp?logID=1871进行了一些讨论和实验,在讨论到用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 XSD datatype to a ADO datatype Select Case vsType Case "xsd:string" GetDataType = adVarChar Case "xsd:int" GetDataType = adInteger Case "xsd:dateTime" GetDataType = adDate Case "xsd:decimal" GetDataType = adDouble Case "xsd:boolean" GetDataType = adBoolean End Select End Function 对于GetDataType中的类型我没有一一试过,只使用了常见的几个,具体的可以参见下面的链接: http://msdn.microsoft.com/library/default.asp?url=/library ... efsupporteddatatypeconversions.asp http://msdn.microsoft.com/library/default.asp?ur ... 270/htm/mdcstdatatypeenum.asp 继续添加,以保证能够符合你具体的需要。然后套用我们在第三篇中的表现层的函数显示在一个Grid中: Set RetXML = SoapClient.GetAuthors() Set result = ConvDatasetToRecordset(RetXML, “GetAuthors”) LvwHeadName lstAuthors, strHeaders ADOFillLvw result, lstAuthors
想想挺有意思,开始是ADODB.Recordset类型的,然后在WebService中转换成DataSet类型,然后又转换成ADODB.Recordset。XML是一个强大的介质,而dotNET中对于Dataset比上一版的Recordset也将是一种突破。对于DataSet的应用也将是极其灵活和没有限制的,因为它的核心和基础是XML。
ByVal sTableName As String, _
ByVal bReturnFieldHeaders As Boolean) As Variant
Dim XDD As DOMDocument
Dim XDLStructure As IXMLDOMNodeList
Dim XDLRows As IXMLDOMNodeList
Dim lcntRows As Long
Dim lctrRow As Long
Dim lcntFields As Long
Dim saFieldDefinitions() As String ' 用于存储字段名和字段 _
' 数据类型的数组。
Dim lctrFieldDef As Long
Dim iRowHeader As Long
Dim vArray() As Variant ' 由函数返回的表格数据的数组。
Dim iCntUbound As Integer
Dim iCtr As Integer
Dim sNodeName As String
Dim xdlFields As IXMLDOMNodeList
Dim xdnField As IXMLDOMNode
Dim iNode As Integer
Dim sDataSetNameSpace As String
On Error GoTo err
Screen.MousePointer = 11
Set XDD = New DOMDocument
With XDD
' 加载字段定义 XML。
.async = False
.preserveWhiteSpace = True
.setProperty "SelectionNamespaces", _
"xmlns:xs='http://www.w3.org/2001/XMLSchema'"
.loadXML xdlXSDFromSoapClient.Item(0).xml
Set XDLStructure = XDD.selectNodes("//xs:element[@name='" & _
sTableName & _
"']/xs:complexType/xs:sequence/xs:element")
' 导入字段定义数组。
lcntFields = XDLStructure.Length - 1 ' 基于零。
If lcntFields = -1 Then
' MsgBox "指定的表格不存在。"
GoTo err
End If
End With
ReDim saFieldDefinitions(lcntFields, 1) As String
For lctrFieldDef = 0 To lcntFields
With XDLStructure.Item(lctrFieldDef).Attributes
saFieldDefinitions(lctrFieldDef, 0) = .getNamedItem("name").Text
saFieldDefinitions(lctrFieldDef, 1) = .getNamedItem("type").Text
End With
Next
' 开始建立数组。
With xdlXSDFromSoapClient.Item(1).firstChild.Attributes
sDataSetNameSpace = .getNamedItem("xmlns").Text
End With
Set XDD = New DOMDocument
With XDD
.async = False
.preserveWhiteSpace = True
.loadXML xdlXSDFromSoapClient.Item(1).xml
If sDataSetNameSpace = "" Then
Set XDLRows = XDD.selectNodes("//" & sTableName)
Else
.setProperty "SelectionNamespaces", "xmlns:df='" & _
sDataSetNameSpace & "'"
Set XDLRows = XDD.selectNodes("//df:" & sTableName)
End If
End With
lcntRows = XDLRows.Length - 1 ' 从 0 开始索引
If lcntRows = -1 Then
MsgBox "XSD Web Service returned no records", vbCritical, "No Data"
Exit Function
End If
' 添加行标题(可选)。
If bReturnFieldHeaders = True Then
' 添加标题行。
ReDim vArray(lcntRows + 1, lcntFields) As Variant
iRowHeader = 1 ' 添加行标题。
For lctrFieldDef = 0 To lcntFields
vArray(0, lctrFieldDef) = _
Replace(saFieldDefinitions(lctrFieldDef, 0), _
"_x0020_", " ")
Next
Else
' 无标题行。
ReDim vArray(lcntRows, lcntFields) As Variant
iRowHeader = 0 ' 无行标题
End If
' 向数组添加行数据。
iCntUbound = UBound(saFieldDefinitions)
For lctrRow = 0 To lcntRows
Set xdlFields = XDLRows.Item(lctrRow).childNodes
For Each xdnField In xdlFields
' 循环将索引放到字段名和数据类型中。
sNodeName = xdnField.nodeName
For iCtr = 0 To iCntUbound
If saFieldDefinitions(iCtr, 0) = sNodeName Then
iNode = iCtr
Exit For
End If
Next Select Case saFieldDefinitions(iNode, 1)
Case "xs:int"
vArray(lctrRow + iRowHeader, iNode) = CLng(xdnField.Text)
Case "xs:integer"
vArray(lctrRow + iRowHeader, iNode) = CVar(xdnField.Text)
Case "xs:long"
vArray(lctrRow + iRowHeader, iNode) = CVar(xdnField.Text)
Case "xs:date"
vArray(lctrRow + iRowHeader, iNode) = _
ConvertISO8601DateFormatToVBDateTime(xdnField.Text)
Case "xs:dateTime"
vArray(lctrRow + iRowHeader, iNode) = _
ConvertISO8601DateFormatToVBDateTime(xdnField.Text)
Case "xs:double"
vArray(lctrRow + iRowHeader, iNode) = CDbl(xdnField.Text)
Case "xs:short"
vArray(lctrRow + iRowHeader, iNode) = CInt(xdnField.Text)
Case "xs:float"
vArray(lctrRow + iRowHeader, iNode) = CSng(xdnField.Text)
Case "xs:boolean"
vArray(lctrRow + iRowHeader, iNode) = CBool(xdnField.Text)
Case "xs:byte"
vArray(lctrRow + iRowHeader, iNode) = CInt(xdnField.Text)
Case "xs:time"
vArray(lctrRow + iRowHeader, iNode) = _
ConvertISO8601DateFormatToVBDateTime(xdnField.Text)
Case Else
vArray(lctrRow + iRowHeader, iNode) = xdnField.Text
End Select
Next
Next
ParseDataSet = vArray
err:
' MsgBox err.Description
' ShowStatus False
Screen.MousePointer = 0
Set XDD = Nothing
Set XDLStructure = Nothing
Set XDLRows = Nothing
Set xdlFields = Nothing
Set xdnField = Nothing
End FunctionPrivate Function ConvertISO8601DateFormatToVBDateTime(ByRef vData As Variant) As Variant
Dim lMonthSep As Long ' 月份分隔符位置。
Dim lDaySep As Long ' 日期分隔符位置。
Dim lMinutesSep As Long ' 分钟分隔符位置。
Dim sDt As String
Dim sTm As String
lMonthSep = InStr(1, vData, "-", vbBinaryCompare)
lDaySep = InStr(lMonthSep + 1, vData, "-", vbBinaryCompare)
If lMonthSep > 0 Then
sDt = Mid(vData, lMonthSep + 1, 2) & "/" & _
Mid(vData, lDaySep + 1, 2) & "/" & _
Left(vData, lMonthSep - 1)
End If ' 提取时间。
lMinutesSep = InStr(1, vData, ":", vbBinaryCompare)
If lMinutesSep > 0 Then
sTm = Mid(vData, lMinutesSep - 2, 8)
End If
ConvertISO8601DateFormatToVBDateTime = CDate(sDt & " " & sTm)
End Function