VERSION 1.0 CLASS BEGIN MultiUse = -1 'True Persistable = 0 'NotPersistable DataBindingBehavior = 0 'vbNone DataSourceBehavior = 0 'vbNone MTSTransactionMode = 0 'NotAnMTSObject END Attribute VB_Name = "CXMLRPCRequest" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = True Attribute VB_PredeclaredId = False Attribute VB_Exposed = False Public Sub decodeResponse(ByRef xml As MSXML2.DOMDocument, ByRef argv As Variant, ByRef fault As Boolean) Dim nodes As MSXML2.IXMLDOMNodeList Dim av As New CAssocItem Set nodes = xml.selectNodes("/methodResponse/fault/value/*") If nodes.length() > 0 Then fault = True Set av = decodeData(nodes.item(0)) Else fault = False Set nodes = xml.selectNodes("/methodResponse/params/param/value/*") If nodes.length() > 0 Then Set av = decodeData(nodes.item(0)) Else Call Err.Raise(-1, , "Invalid XML response.") End If End If If IsObject(av.value) Then Set argv = av.value Else argv = av.value End If Set nodes = Nothing Set av = Nothing End Sub Private Function decodeData(ByRef node As MSXML2.IXMLDOMNode) As CAssocItem Dim i As Long Dim nodes As MSXML2.IXMLDOMNodeList Dim key As String Dim value As CAssocItem Dim itime As New CInetTime Dim b64 As New CBase64 Dim tmpNode As MSXML2.IXMLDOMNode Dim text As String Set decodeData = New CAssocItem If node.nodeName = "array" Then Set nodes = node.selectNodes("data/value") Set decodeData.value = New Collection For i = 0 To nodes.length() - 1 Set value = decodeData(nodes.item(i).firstChild) Call decodeData.value.Add(value.value) Next ElseIf node.nodeName = "struct" Then Set nodes = node.selectNodes("member") Set decodeData.value = New CAssocArray For i = 0 To nodes.length() - 1 key = nodes.item(i).selectSingleNode("name/text()").nodeValue Set value = decodeData(nodes.item(i).selectSingleNode("value/*")) Call decodeData.value.Add(key, value.value) Next Else Set tmpNode = node.selectSingleNode("text()") If tmpNode Is Nothing Then text = "" Else text = tmpNode.nodeValue End If If node.nodeName = "boolean" Then decodeData.value = CBool(CLng(text)) ElseIf node.nodeName = "int" Or node.nodeName = "i4" Then decodeData.value = CLng(text) ElseIf node.nodeName = "double" Then decodeData.value = CDbl(text) ElseIf node.nodeName = "dateTime.iso8601" Then decodeData.value = itime.InternetTimeToVbLocalTime(text) ElseIf node.nodeName = "base64" Then decodeData.value = b64.DecodeBase64(text) ElseIf node.nodeName = "string" Then decodeData.value = CStr(text) Else Call Err.Raise("Unknown type.", , -1) End If End If End Function Public Sub encodeRequest(ByVal method As String, ByRef request As Variant, ByRef xml As String) Dim src As String Dim av As New CAssocItem If IsObject(request) Then Set av.value = request Else av.value = request End If src = "" & _ "" & _ "" & escapeXMLString(method) & "" & _ "" & _ encodeData(av) & _ "" & _ "" ' Set xml = New MSXML2.DOMDocument ' Call xml.loadXML(src) xml = src ' Set av = Nothing End Sub Private Function encodeData(ByRef item As CAssocItem) As String Dim itime As New CInetTime Dim av As New CAssocItem Dim v As Variant Dim b64 As CBase64 Dim itemType As VariantTypeConstants Dim itemObjType As String itemType = VarType(item.value) If itemType = vbObject Then itemObjType = TypeName(item.value) If itemObjType = "CAssocArray" Then encodeData = "" For Each av In item.value encodeData = encodeData & "" & _ "" & escapeXMLString(av.key) & "" & _ "" & encodeData(av) & "" & _ "" Next encodeData = encodeData & "" ElseIf itemObjType = "Collection" Then encodeData = "" For Each v In item.value av.value = v encodeData = encodeData & "" & encodeData(av) & "" Next encodeData = encodeData & "" Else Call Err.Raise(-1, , "Unsupported object type: " + itemObjType) End If ElseIf itemType = vbBoolean Then encodeData = "" & IIf(item.value, "1", "0") & "" ElseIf itemType = vbInteger Or itemType = vbLong Then encodeData = "" & Trim(CStr(item.value)) & "" ElseIf itemType = vbSingle Or itemType = vbDouble Then encodeData = "" & Trim(CStr(item.value)) & "" ElseIf itemType = vbDate Then encodeData = "" & _ escapeXMLString(itime.VbLocalTimeToInternetTime(item.value, "iso8601")) & _ "" ElseIf itemType = vbString Or itemType = vbCurrency Or itemType = vbDecimal Then encodeData = "" & escapeXMLString(item.value) & "" ' ElseIf itemType = vbByte + vbArray Then ' encodeData = b64.EncodeBase64(item.value) '' !!!!!!!!! Base64 not supported Else Call Err.Raise(-1, , "Unknown type: " + CStr(itemType)) End If Set v = Nothing End Function Private Function escapeXMLString(str As String) str = Replace(str, "&", "&") str = Replace(str, "<", "<") str = Replace(str, ">", ">") str = Replace(str, Chr(34), """) escapeXMLString = Replace(str, "'", "'") End Function Public Function doCall(url As String, method As String, ByRef params As Variant, ByRef result As Variant) As Boolean Dim http As New MSXML2.ServerXMLHTTP60 Dim xml As String If Not IsObject(params) And VarType(params) = vbEmpty Then params = "" End If Call encodeRequest(method, params, xml) Call http.Open("POST", url, False) Call http.send(xml) ' Настраивайте прокси, если нужно. По умолчанию работает без прокси! If http.Status <> 200 Then Set http = Nothing doCall = False Call Err.Raise(-1, , "Ошибка зароса на сервер XML-RPC.") End If Call decodeResponse(http.responseXML, result, doCall) Set http = Nothing End Function