Ошибочно смешивать объекты из разных версий msxml
Я использую 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 ответа
На самом деле не очень люблю публиковать ответы, которые я не могу проверить, но здесь идет.
В вашей топовой версии вы используете прямой 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.
Так как вы создали 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