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

时间:2017-10-16 19:00:10

标签: xml vba excel-vba selectsinglenode excel

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

答案 0 :(得分:1)

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

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

具体来说,/r:NDA表示从名为&#34; NDA&#34;的文档元素开始此位置路径。在由&#34; r&#34;表示的命名空间中。更改您调用selectSingleNode的元素不会改变此位置路径的结果。在Excel术语中,它就像在公式中使用$A$1一样 - 无论您在何处复制此公式,它都将始终引用单元格A1。

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

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

此位置路径的结果取决于上下文节点 - childNodes(i)。它检查上下文节点本身是否被调用&#34; TID&#34;在由&#34; r&#34;表示的命名空间中并相应地输出细节。

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

相关问题