Как можно ближе к вашему ОП
Обращаю ваше внимание на несколько ошибок или недоразумений:
[1]
Неверный .LoadXML
Синтаксис
В чем же разница между .LoadXML ("C: \ folder \ folder \ name.xml") и .Load ("C: \ folder \ folder \ name.xml ")?
Load
ожидает путь к файлу и затем загружает содержимое файла в объект oXML.
LoadXML
не ожидает параметр файла, но его фактическое текстовое содержимое XML , которое должно быть правильно сформированной строкой.
[2]
XML различает строчные и прописные буквы, поэтому узлы должны быть адресованы их точными литеральными именами: узел <Query>
не будет идентифицирован с помощью "query" , "ConceptModel" не совпадает с " conceptmodel ".
В качестве второго вопроса я хотел бы спросить, если Dim oXml As MSXML2.DOMDocument
будет таким же, как Dim oXml As MSXML2.DOMDocument60
, с тех пор, как я проверил инструменты / ссылки "Microsof XML, v6.0"?
Нет, это не так.- Обратите внимание, что предыдущее объявление будет загружать версию 3.0 по умолчанию.Однако абсолютно желательно получить версию 6.0 (в настоящее время любые другие версии устарели!)
Поскольку вы используете так называемое раннее связывание (ссылаясь на «Microsoft XML, v6.0»),Я сделаю то же самое, но имею в виду текущую версию 6.0:
Dim oXml As MSXML2.DOMDocument60 ' declare the xml doc object
Set oXml = New MSXML2.DOMDocument60 ' set an instance of it to memory
[3]
неправильное понимание некоторых выражений XPath
Aначальная косая черта "/" в выражении XPath всегда относится к DocumentElement (<Concepts>
здесь), вместо этого вы можете добавить .DocumentElement
к объекту документа.Начальная двойная косая черта "// xyz" найдет любой узел "xyz", если он существует.
Например,
oXml.SelectNodes("//Query").Length
возвращает тот же номер childNodes (здесь: 3), что и
oXml.DocumentElement.SelectNodes("//Query").Length ' or
oXml.SelectSingleNode("//Queries").ChildNodes.Length ' or even
oXml.SelectNodes("/*/*/*/Query").Length`.
Пример кода со ссылкой на версию XML 6.0
Конечно, вам придется зацикливаться на нескольких файлах XML, в примере используется только один (начиная со строки 2).
Только для случая не правильно сформированных XML-файлов Я добавил детализированную подпрограмму ошибки , которая позволяет идентифицировать предполагаемое место ошибки.Load
и LoadXML
оба возвращают логическое значение (True, если загружено правильно, False, если нет).
Sub xmlTest()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets(3)
Dim oXml As MSXML2.DOMDocument60
Set oXml = New MSXML2.DOMDocument60
With oXml
.validateOnParse = True
.setProperty "SelectionLanguage", "XPath" ' necessary in version 3.0, possibly redundant here
.async = False
If Not .Load(ThisWorkbook.Path & "\xml\" & "name.xml") Then
Dim xPE As Object ' Set xPE = CreateObject("MSXML2.IXMLDOMParseError")
Dim strErrText As String
Set xPE = .parseError
With xPE
strErrText = "Load error " & .ErrorCode & " xml file " & vbCrLf & _
Replace(.URL, "file:///", "") & vbCrLf & vbCrLf & _
xPE.reason & _
"Source Text: " & .srcText & vbCrLf & vbCrLf & _
"Line No.: " & .Line & vbCrLf & _
"Line Pos.: " & .linepos & vbCrLf & _
"File Pos.: " & .filepos & vbCrLf & vbCrLf
End With
MsgBox strErrText, vbExclamation
Set xPE = Nothing
Exit Sub
End If
' Debug.Print "|" & oXml.XML & "|"
Dim Queries As IXMLDOMNodeList, Query As IXMLDOMNode
Dim Searched As String
Dim i&, ii&
i = 2 ' start row
' start XPath
Searched = "ConceptModel/Queries/Query" ' search string
Set Queries = oXml.DocumentElement.SelectNodes(Searched) ' XPath
'
ws.Cells(i, 1) = IIf(Queries.Length = 0, "No items", Queries.Length & " items")
ii = 1
For Each Query In Queries
ii = ii + 1
ws.Cells(i, ii) = Query.Text
Next
End With
End Sub
Дополнительные подсказки
Вы также можете бытьинтересует пример, как вывести список всех дочерних узлов через XMLDOM и получить имена атрибутов из XML с помощью VBA .
Я включил еще одну подсказку из-за более позднего комментария (спасибо @barrowc)
"Еще одна проблема с использованием MSXML v3.0 заключается в том, что язык выбора по умолчаниюэто XSLPatterns вместо XPath. Подробности некоторых различий между версиями MSXML здесь , а различия между двумя языками выбора обсуждаются здесь . "
В текущей версии MSXML2 6.0 XPath 1.0 полностью поддерживается.Похоже, что XSL Patterns были реализованы Microsoft ранее, в основном это можно рассматривать как упрощенное подмножество выражений XPath до стандартизации XPath в W3C.
MSXML2 версии 3.0 позволяет интегрироватьXPath 1.0 хотя бы с помощью явного выбора языка:
oXML.setProperty "SelectionLanguage", "XPath" ' oXML being the DOMDocument object as used in original post