在VBA中获取XML响应中的值

时间:2013-12-19 20:50:29

标签: xml vba excel-vba excel

我正在使用GET请求从Web服务获取XML响应。我正在尝试解析响应并以VBA形式显示其中的一部分。 VBA组件我认为我有很好的处理,但XML语法给我带来了很多问题。这是我到目前为止在VBA中的子目录:

Sub GetCANSIM()
Dim XMLRequest As New XMLHTTP
Dim objXML As MSXML2.DOMDocument
Dim point As IXMLDOMNode
Dim value As Variant
Dim lngYear As Long

Set objXML = New MSXML2.DOMDocument

XMLRequest.Open "GET", "someURL", False
XMLRequest.send

While XMLRequest.Status <> 200
    DoEvents
Wend

If Not objXML.LoadXML(XMLRequest.responseText) Then
    Err.Raise objXML.parseError.ErrorCode, , objXML.parseError.reason
End If

End Sub

我正在使用Microsoft XML V6.0参考。

XML响应非常大,但这是它的格式:

<DataSet>
<xs:schema id="NewDataSet">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="CANSIM">
<xs:complexType>
<xs:sequence>
<xs:element name="ID" type="xs:int" minOccurs="0"/>
<xs:element name="Date" type="xs:dateTime" minOccurs="0"/>
<xs:element name="Year" type="xs:int" minOccurs="0"/>
<xs:element name="Month" type="xs:int" minOccurs="0"/>
<xs:element name="BondYield_LongTerm_Gov" type="xs:double" minOccurs="0"/>
<xs:element name="BondYield_LongTerm_Prov" type="xs:double" minOccurs="0"/>
<xs:element name="BondYield_LongTerm_Corp" type="xs:double" minOccurs="0"/>
<xs:element name="B14070" type="xs:double" minOccurs="0"/>
<xs:element name="B14072" type="xs:double" minOccurs="0"/>
<xs:element name="B14081" type="xs:double" minOccurs="0"/>
<xs:element name="B14045" type="xs:double" minOccurs="0"/>
<xs:element name="Rolling12MonthAvg" type="xs:double" minOccurs="0"/>
<xs:element name="B14055" type="xs:double" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<diffgr:diffgram>
<NewDataSet>
<CANSIM diffgr:id="CANSIM1" msdata:rowOrder="0">
<ID>462</ID>
<Date>2006-06-01T00:00:00-04:00</Date>
<Year>2006</Year>
<Month>6</Month>
<BondYield_LongTerm_Gov>0.0469</BondYield_LongTerm_Gov>
<BondYield_LongTerm_Prov>0.0518</BondYield_LongTerm_Prov>
<BondYield_LongTerm_Corp>0.0581</BondYield_LongTerm_Corp>
<B14070>0.0458</B14070>
<B14072>0.0467</B14072>
<B14081>0.019</B14081>
<B14045>0.0318</B14045>
<Rolling12MonthAvg>0.026425</Rolling12MonthAvg>
<B14055>0.0328</B14055>
</CANSIM>
<CANSIM diffgr:id="CANSIM2" msdata:rowOrder="1">
<ID>463</ID><Date>2006-07-01T00:00:00-04:00</Date><Year>2006</Year><Month>7</Month>
<BondYield_LongTerm_Gov>0.0446</BondYield_LongTerm_Gov>  
<BondYield_LongTerm_Prov>0.0496</BondYield_LongTerm_Prov>
<BondYield_LongTerm_Corp>0.056</BondYield_LongTerm_Corp>
<B14070>0.0431</B14070>
<B14072>0.0445</B14072>
<B14081>0.018</B14081>
<B14045>0.0318</B14045>
<Rolling12MonthAvg>0.027216666667</Rolling12MonthAvg>
<B14055>0.0328</B14055>
</CANSIM>
</NewDataSet>
</diffgr:diffgram>
</DataSet>

我想在过去5年的第12个月中获取“B14045”率和“Rolling12MonthAvg”的最后60个月。

这些值都是有序的,所以我想我应该能够通过使用“月”和“年”属性“找到”或“转到”开始月份(60个月前),然后阅读B14045率在递增循环中。

但是我不知道找到我想要的节点(?)的语法然后向前递增。我已经尝试过阅读一些帮助文件和其他主题,但我似乎无法做出正面或反面。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

我认为我使用:http://www.w3schools.com/xpath/xpath_examples.asp

找出了XML语法
Sub GetCANSIM()
Dim XMLRequest As New XMLHTTP
Dim objXML As MSXML2.DOMDocument
Dim objNodeList As IXMLDOMNodeList
Dim objNode As IXMLDOMNode
Dim objElement As IXMLDOMElement
Dim strPath As String
Dim lngYear As Long

Set objXML = New MSXML2.DOMDocument

XMLRequest.Open "GET", "someURL",False
XMLRequest.send

While XMLRequest.Status <> 200
    DoEvents
Wend

If Not objXML.LoadXML(XMLRequest.responseText) Then
    Err.Raise objXML.parseError.ErrorCode, , objXML.parseError.reason
End If

objXML.setProperty "SelectionLanguage", "XPath"

lngYear = year(Now()) - 8

'Select all the B14045 elements of the CANSIM elements which are within 5 years
strPath = "//CANSIM[Year>" & lngYear & "]/B14045"

Set objNodeList = objXML.DocumentElement.SelectNodes(strPath)

End Sub