我调用一个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里不会,可否路过的朋友有知道的告之一声,不胜感激,我的一百分都给你,说话算话.

解决方案 »

  1.   

    没办法直接到recordset里面的,
    格式与Recordset产生的xml不一样的,
    只有用Xsl和DOM来转化了
      

  2.   

    可否给个转换的例子Dim node, i, j, subnodecount, nodecount
    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()
      

  3.   

    我调取的是一个web services 返回类型为DataSet型的,所以比较麻烦
      

  4.   

    '试试以下代码,应该可以把你上面的xml字符串,放到recordset中的! Dim objXML As New MSXML2.DOMDocument40 
    Dim objRS As RecordsetIf objXML.loadXML(strXML) Then
       Set objRS = New Recordset
       objRS.Open objXML
    End if ===============
    楼主应该可以用
    MSXML.XMLHTTPRequest 来取得xml串,楼主应该有这方面的代码了吧,我就不贴了
      

  5.   

    将ADO.NET或Webservice返回的DataSet转换成ADODB.Recordset 
    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。 
      

  6.   

    我这个Web service 有五个函数,我用了一个叫什么office 2003 for web services 的控件,他返回我的五个函数类型是MSXML2.IXMLDOMNodeList      我试了一下Modest(塞北雪貂 -- 偶最欣赏楼主的分)  ConvDatasetToRecordset函数好像在GCall retRS.Fields.Append(iXMLFieldNode.Attributes(0).Text, GetDataType(iXMLFieldNode.Attributes这里会报错. 错误是不可预计的错误
      

  7.   

    Public Function ParseDataSet(ByRef xdlXSDFromSoapClient As IXMLDOMNodeList, _
                                 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