ошибочно смешивать объекты из разных версий msxml - PullRequest
0 голосов
/ 28 августа 2018

Я использую Excel VBA и пытаюсь добиться следующего:

1) Отправьте HTTP-запрос и получите возвращенный XML 2) Выберите некоторые элементы из возвращенного XML и добавьте их в другой XML DOM с помощью метода appendChild.

Я получил ошибку во время выполнения "это ошибка смешивания объектов из разных версий 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 голосов
/ 26 сентября 2018

Поскольку вы создали объект Http с помощью ProgID MSXML2.ServerXMLHTTP, который является независимым от версии ProgID, который по умолчанию равен MSXML2.ServerXMLHTTP.3.0; с помощью метода 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
0 голосов
/ 28 августа 2018

На самом деле не очень люблю публиковать ответы, которые я не могу проверить, но здесь идет.

В вашей топовой версии вы используете прямой XML-ответ без помощи парсера XML. Эта ссылка описывает вашу ошибку следующим образом:

Причина

Когда вы смешиваете разные версии объектов MSXML DOM в DOM вызов метода объекта, объект из другой версии синтаксический анализатор, который предоставляется как обязательный параметр метода, рассматривается как иностранный объект.

Разрешение

Ссылка и использование объектов, реализованных в одной версии синтаксического анализатора MSXML. Не> смешивайте разные версии объектов DOM при программировании DOM MSXML.

Таким образом, при использовании direct, возможно, вы имеете дело с объектом, реализованным другой версией синтаксического анализатора MSXML.

Я думал, что вам всегда нужно было проанализировать ответ на стороне клиента XML-анализатора, прежде чем исследовать DOM. Это позволяет вам указать / контролировать версию парсера во всем вашем коде. Это также позволяет вам 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 о XML Dom .

...