VBA - SelectSingleNode извлекает только первый узел из списка
Я использую VBA для работы с XML-файлом. MS Offfice - 2013. Я добавил библиотеку - Microsoft XML Version6.0. Пожалуйста, найдите ниже xml, а также код. Я пытаюсь получить все TID в XML и написать на листе. Но selectsinglenode() извлекает только первый узел. Что я делаю неправильно? Есть ли способ использовать selectsinglenode для возврата каждого TID? Пожалуйста, предложите. Дайте мне знать, если вам нужна дополнительная информация.
<NDA xmlns="http://www.example.com">
<FileHeader>
<Form>7</Form>
<SID>1521</SID>
</FileHeader>
<Subdivision>
<SID>1521</SID>
<CID>200</CID>
<Version>1</Version>
</Subdivision>
<BC>
<BF>
<BElem>
<BFountain>
<BFeature>
<Start>0</Start>
<End>279</End>
<TType>2</TType>
<SLimit>25</SLimit>
<SIT>3</SIT>
<RBTField>0</RBTField>
<RType>1</RType>
<RParam>0</RParam>
<RParamOp>5</RParamOp>
<TID>4015100639</TID>
</BFeature>
<BFeature>
<Start>0</Start>
<End>279</End>
<TType>1</TType>
<SLimit>50</SLimit>
<SIT>3</SIT>
<RBTField>0</RBTField>
<RType>2</RType>
<RParam>0</RParam>
<RParamOp>5</RParamOp>
<TID>2850474662</TID>
</BFeature>
<BFeature>
<Start>0</Start>
<End>279</End>
<TType>1</TType>
<SLimit>25</SLimit>
<SIT>3</SIT>
<RBTField>0</RBTField>
<RType>1</RType>
<RParam>0</RParam>
<RParamOp>5</RParamOp>
<TID>2563719215</TID>
</BFeature>
<BFeature>
<Start>0</Start>
<End>279</End>
<TType>3</TType>
<SLimit>25</SLimit>
<SIT>3</SIT>
<RBTField>0</RBTField>
<RType>1</RType>
<RParam>0</RParam>
<RParamOp>5</RParamOp>
<TID>1962204848</TID>
</BFeature>
</BFountain>
</BElem>
</BF>
</BC>
</NDA>
Ниже приведен код:
Dim xDoc1 As MSXML2.DOMDocument60
Dim xNodeList1 As MSXML2.IXMLDOMNodeList
Dim xNode1 As MSXML2.IXMLDOMNode
Dim xChildNode1 As MSXML2.IXMLDOMNode
Dim xpathToExtractRow1 As String, XMLNamespaces1 As String
Dim wCompareWorksheet As Excel.Worksheet
Dim sFoundNode As MSXML2.IXMLDOMNode
Set xDoc1 = New MSXML2.DOMDocument60
xDoc1.async = False
xDoc1.validateOnParse = False
XMLNamespaces1 = "xmlns:r='http://www.example.com"
xDoc1.Load ("ABCD.xml")
xDoc1.setProperty "SelectionNamespaces", XMLNamespaces1
xDoc1.setProperty "SelectionLanguage", "XPath"
If xDoc1.parseError.ErrorCode <> 0 Then
Set oErr1 = xDoc1.parseError
Debug.Print oErr1.reason
End If
Set xNodeList1 = xDoc1.SelectNodes("/r:NDA/r:BC/r:BF/r:BElem/r:BFountain/r:BFeature")
z=1
For x = 0 To xNodeList1.Length - 1
bFirstChild = True
If xNodeList1.Item(x).HasChildNodes Then
For i = 0 To xNodeList1.Item(x).ChildNodes.Length - 1
Set sFoundNode = xNodeList1.Item(x).ChildNodes(i).SelectSingleNode("/r:NDA/r:BC/r:BF/r:BElem/r:BFountain/r:BFeature/r:TID")
If Not sFoundNode Is Nothing Then
wCompareWorksheet.Cells(z, 1) = x & "," & i
wCompareWorksheet.Cells(z, 4) = sFoundNode.nodeName
wCompareWorksheet.Cells(z, 6) = sFoundNode.Text
z = z + 1
Else
Debug.Print "sFound is nothing"
End If
Next
End If
Next
1 ответ
Ваш код использует абсолютный путь местоположения (это абсолютный путь местоположения, потому что он начинается с /
):
.selectSingleNode("/r:NDA/r:BC/r:BF/r:BElem/r:BFountain/r:BFeature/r:TID")
В частности, /r:NDA
означает запуск этого пути к местоположению из элемента документа с именем "NDA" в пространстве имен, обозначенном "r". Изменение элемента, который вы называете selectSingleNode
on не изменит результаты этого пути местоположения. В терминах Excel это похоже на использование $A$1
в формуле - где бы вы ни копировали эту формулу, она всегда будет ссылаться на ячейку A1.
Вам нужно либо использовать selectNodes
(как предлагается в комментариях) или использовать selectSingleNode
с относительным расположением пути, как это:
Set sFoundNode = xNodeList1.Item(x).ChildNodes(i).selectSingleNode("self::r:TID")
Результат этого пути расположения зависит от узла контекста - childNodes(i)
, Он проверяет, называется ли сам контекстный узел "TID" в пространстве имен, обозначенном "r", и выводит подробности соответственно.
Это не очень разумный способ достижения этого результата. Вы можете просто проверить nodeName
атрибут каждого дочернего узла напрямую. Еще лучше, вы могли бы использовать selectNodes
найти все r:TID
узлы сразу, а затем выполнить любые необходимые манипуляции с ними