【问题标题】:VBA - Loop specific childnodes from XML codeVBA - 从 XML 代码循环特定子节点
【发布时间】:2015-10-03 09:21:59
【问题描述】:

我正在尝试将以下 Xml 抓取到 Excel 工作表中。但是,我只想遍历特定的子节点以显示每个索引摘要的 NamePriceEffectiveStartPriceEffectiveEndPriceCurrency

XML 代码

<indexPrices>
     <indexPriceSummary>
         <id>1</id>
         <uri>www.example.com</uri>
      <index>
        <id>3</id>
        <name>Same Day Index</name>
        <uri>www.example.com.xml</uri>
      </index>
      <priceEffectiveStart>2015-06-26</priceEffectiveStart>
      <priceEffectiveEnd>2015-06-26</priceEffectiveEnd>
      <price>
         <amount>2.4806</amount>
         <currency>CAD</currency>
      </price>
      <duration>1</duration>
      <quantityTraded>
        <amount>474</amount>
        <unit>GJ</unit>
        <contractUnit>Day</contractUnit>
      </quantityTraded>
      <numberOfTrades>7</numberOfTrades>
      <settlementState>Settled</settlementState>
      <lastUpdateDate>2015-06-27T02:15:01-06:00</lastUpdateDate>
    </indexPriceSummary>
    <indexPriceSummary>
        <id>1</id>
        <uri>www.example.com.xml</uri>
     <index>
      <id>1</id>
      <name>Same Day Index </name>
      <uri>www.example.com.xml</uri>
     </index>
     <priceEffectiveStart>2015-06-27</priceEffectiveStart>
     <priceEffectiveEnd>2015-06-27</priceEffectiveEnd>
     <price>
         <amount>2.516</amount>
         <currency>CAD</currency>
     </price>
     <duration>1</duration>
     <quantityTraded>
        <amount>251</amount>
        <unit>GJ</unit>
        <contractUnit>Day</contractUnit>
     </quantityTraded>
     <numberOfTrades>50</numberOfTrades>
     <settlementState>Settled</settlementState>
     <lastUpdateDate>2015-06-28T02:15:00-06:00</lastUpdateDate>
   </indexPriceSummary>
</IndexPrices>

VBA 代码

Dim xDoc As DOMDocument
Set xDoc = New DOMDocument

xDoc.LoadXML objHTTP.responseText

Dim i As Integer
Dim list As IXMLDOMNodeList
Set list = xDoc.SelectNodes("//indexPrices/indexPriceSummary")

Dim node As IXMLDOMNode
Dim childNode As IXMLDOMNode
Dim price As IXMLDOMNode

For Each node In list
    i = i + 1

    If (node.HasChildNodes) Then
        For Each childNode In node.ChildNodes
             i = i + 1
            Debug.Print childNode.BaseName & " " & childNode.Text
             Worksheets("Sheet1").Cells(i, 1) = childNode.BaseName
             Worksheets("Sheet1").Cells(i, 2) = childNode.Text
        Next childNode
    End If


  Next node

当前 VBA 显示输出中的所有节点。我希望它只显示每个索引摘要的 NamePriceEffectiveStartPriceEffectiveEndPriceCurrency

【问题讨论】:

    标签: excel xml vba


    【解决方案1】:

    您可以在每个 indexPriceSummary 节点上使用 xpath 直接获取子元素:

    Sub Tester()
        Dim xDoc As DOMDocument
        Set xDoc = New DOMDocument
    
        ''more code here
    
    
        xDoc.LoadXML objHTTP.responseText
    
        Dim i As Integer
        Dim list As IXMLDOMNodeList
        Set list = xDoc.SelectNodes("//indexPrices/indexPriceSummary")
    
        Dim node As IXMLDOMNode, nd As IXMLDOMNode
        Dim childNode As IXMLDOMNode
        Dim price As IXMLDOMNode
    
        i = 4
        For Each node In list
            i = i + 1
    
            With Sheet1.Rows(i)
                .Cells(1).Value = GetNodeValue(node, "index/name")
                .Cells(2).Value = GetNodeValue(node, "priceEffectiveStart")
                .Cells(3).Value = GetNodeValue(node, "priceEffectiveEnd")
                .Cells(4).Value = GetNodeValue(node, "price/amount")
                .Cells(5).Value = GetNodeValue(node, "price/currency")
            End With
    
        Next node
    
    End Sub
    
    Function GetNodeValue(node As IXMLDOMNode, xp As String)
        Dim n As IXMLDOMNode, nv
        Set n = node.SelectSingleNode(xp)
        If Not n Is Nothing Then nv = n.nodeTypedValue
        GetNodeValue = nv
    End Function
    

    【讨论】:

    • @Newd 我不能 - 需要 1500 个代表
    • 还要注意 childnodes(i) 有一个可以用作迭代器的索引。因此,您可以使用 Set xmlNodes = xmlDoc.SelectNodes("/.../...") 获得所需的分支级别。计算分支: rws = xmlNodes.length 然后循环遍历它们。 For Each xNode In xmlNodes ... Set dNode = xNode.ChildNodes(c - 1) then Set dNode = dNode.SelectSingleNode("...") then myArray(r, c) = dNode.nodeTypedValue // I put this as评论,因为这不是一个直接的答案,但发现这一点的人可能对获得具有同级节点的某个级别的表/数组非常感兴趣
    猜你喜欢
    • 2014-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-16
    • 2014-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多