VBA - SelectSingleNode 仅检索列表中的第一个节点

VBA - SelectSingleNode retrieves only first node from the list

我正在使用 VBA 来操作 XML 文件。 MS Office - 2013。我添加了库 - Microsoft XML Version6.0。 请在下面找到 xml 以及代码。我正在尝试检索 xml 中的所有 TID 并写入 sheet。但是 selectsinglenode() 只检索第一个节点。我究竟做错了什么?有没有办法使用 selectsinglenode 来 return 每个 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

您的代码使用了绝对位置路径(它是绝对位置路径,因为它以 / 开头):

.selectSingleNode("/r:NDA/r:BC/r:BF/r:BElem/r:BFountain/r:BFeature/r:TID")

具体来说,/r:NDA 表示从"r" 表示的命名空间中名为"NDA" 的文档元素开始此位置路径。更改调用 selectSingleNode 的元素不会改变此位置路径的结果。在 Excel 术语中,这就像在公式中使用 $A - 无论您将此公式复制到哪里,它总是引用单元格 A1。

您需要使用 selectNodes(如评论中所建议)或使用 selectSingleNode 和相对位置路径,如下所示:

Set sFoundNode = xNodeList1.Item(x).ChildNodes(i).selectSingleNode("self::r:TID")

此位置路径的结果取决于上下文节点 - childNodes(i)。它检查上下文节点本身是否在 "r" 表示的命名空间中被称为 "TID" 并相应地输出详细信息。

这不是实现此结果的非常明智的方法。您可以直接检查每个子节点的 nodeName 属性。更好的是,您可以使用 selectNodes 一次找到所有 r:TID 节点,然后对它们执行您需要的任何操作