混合来自不同版本的msxml的对象是错误的

时间:2018-08-28 03:06:12

标签: xml vba dom msxml

我正在使用Excel VBA并尝试实现以下目标:

1)发送HTTP请求并获取返回的XML 2)从返回的XML中选择一些元素,然后使用appendChild方法将其添加到另一个XML DOM。

我遇到运行时错误“混合来自不同版本的msxml的对象是错误”。我找到了一种解决方法,但不确定为什么会发生该错误,并想知道是否有更优雅的方法来解决它。

抛出错误的代码:

Dim sURL as String
Dim Http As Object
Set Http = CreateObject("MSXML2.SERVERXMLHTTP")
Dim xgetCSS As New MSXML2.DOMDocument60
Dim xDoc As New MSXML2.DOMDocument60
Dim xMember As MSXML2.IXMLDOMElement
Dim nodes As MSXML2.IXMLDOMNodeList
Dim node As MSXML2.IXMLDOMElement

Http.Open "Post", sURL, False
Http.send (xgetCSS.XML)

Set nodes = Http.responseXML.SelectNodes("//return/css/members/member")

For Each xMember In nodes
    node.appendChild xMember
Next

解决方法:

Dim sURL as String
Dim Http As Object
Set Http = CreateObject("MSXML2.SERVERXMLHTTP")
Dim xgetCSS As New MSXML2.DOMDocument60
Dim xDoc As New MSXML2.DOMDocument60
Dim xMember As MSXML2.IXMLDOMElement
Dim nodes As MSXML2.IXMLDOMNodeList
Dim node As MSXML2.IXMLDOMElement

Http.Open "Post", sURL, False
Http.send (xgetCSS.XML)

Set nodes = Http.responseXML.SelectNodes("//return/css/members/member")

For Each xMember In nodes
    xDoc.LoadXML xMember.XML
    node.appendChild xDoc.DocumentElement
Next

因此,基本上,我采用了返回的XML的内容,创建了一个新的DOM文档,并使用这个新创建的DOM文档来解决“混合版本”问题。但是有更好的方法吗?谢谢!

2 个答案:

答案 0 :(得分:0)

我不是很热衷于发布我无法测试的答案,但这是可行的。

在最高版本中,您直接使用响应XML,而没有XML解析器的帮助。此link描述您的错误,如下所示:

  

原因

     

在DOM中混合使用不同版本的MSXML DOM对象时   对象的方法调用,来自不同版本的对象   作为必需方法参数提供的解析器被视为   异物。

     

解决方案

     

引用和使用由MSXML解析器的单个版本实现的对象。对MSXML DOM进行编程时,请勿>混合使用不同版本的DOM对象。

因此,当直接使用时,您可能正在处理由不同版本的MSXML解析器实现的对象。

我认为您在探索DOM之前总是需要将响应解析为XML解析器客户端。这使您可以在整个代码中指定/控制解析器的版本。它还允许您validateOnParse并确保xPath可用于定位DOM元素。

我无法测试,但也许如下所示?

Option Explicit
Public Sub HandleXML()
    Dim sURL As String, Http As Object, xgetCSS As New MSXML2.DOMDocument60
    Dim xDoc As New MSXML2.DOMDocument60, xMember As MSXML2.IXMLDOMElement
    Dim nodes As MSXML2.IXMLDOMNodeList, node As MSXML2.IXMLDOMElement

    Set Http = CreateObject("MSXML2.SERVERXMLHTTP")
    With Http
        .Open "Post", sURL, False
        .send xgetCSS.XML
    End With

    With xDoc
        .validateOnParse = True
        .setProperty "SelectionLanguage", "XPath"
        .async = False

        If Not .LoadXML(Http.responseText) Then  '<==Not sure if you need Http.responseXML here as can't test
            Err.Raise .parseError.ErrorCode, , .parseError.reason
            Exit Sub
        End If
    End With

    Set nodes = xDoc.SelectNodes("//return/css/members/member")

    For Each xMember In nodes
        node.appendChild xMember
    Next

End Sub

某些Microsoft info on XML Dom

答案 1 :(得分:0)

自从您使用ProgID Http创建了MSXML2.ServerXMLHTTP对象以来,该对象是defauls to MSXML2.ServerXMLHTTP.3.0的与版本无关的ProgID;使用Http.responseXML方法,您只能拥有一个XML文档,该文档是MSXML2.DOMDocument.3.0的实例。听起来这就是您面临的问题。

您有两种方法可以解决此问题。

1-改用版本相关的ProgID。

Set Http = CreateObject("MSXML2.ServerXMLHTTP.6.0")

2-甚至不使用CreateObject。您已经引用了Microsoft XML v6.0。

Dim Http As MSXML2.ServerXMLHTTP60
Set Http = New MSXML2.ServerXMLHTTP60