You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在VBA中获取ECB汇率XML里父Cube节点的time属性值?

问题描述

通过GET请求获取欧洲中央银行的每日汇率XML数据,需要提取包含time属性的父Cube节点的time值,以此判断是否需要将汇率存入数据库。现有VBA代码能正常提取汇率和货币代码,但无法获取该父节点的time属性,请求解决方法。

XML核心结构示例:

<gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
  <Cube>
    <Cube time="2023-01-06">
      <Cube currency="USD" rate="1.0500"/>
      <!-- 其他汇率节点 -->
    </Cube>
  </Cube>
</gesmes:Envelope>

现有VBA代码片段:

Dim xhr As Object, node As Object
Set exchangeRates = New Collection

Set xhr = CreateObject("msxml2.xmlhttp.6.0")
xhr.Open "GET", "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml", False
xhr.Send

For Each node In xhr.responseXML.SelectNodes("//*[@rate]")
  exchangeRates.Add Conversion.Val(node.GetAttribute("rate")), node.GetAttribute("currency")
  lb_CurrencySelection.AddItem node.GetAttribute("currency")
Next
解决方法

核心问题是XML存在默认命名空间(xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"),直接使用SelectNodes会因命名空间不匹配无法定位节点。需先给默认命名空间注册前缀,再通过前缀查询节点。

步骤1:注册命名空间前缀

在获取XML响应后,为默认命名空间绑定一个自定义前缀(比如ecb):

xhr.responseXML.setProperty "SelectionNamespaces", "xmlns:ecb='http://www.ecb.int/vocabulary/2002-08-01/eurofxref'"

步骤2:获取父Cube节点的time值

通过注册的前缀,使用SelectSingleNode定位带time属性的Cube节点(每日XML仅存在一个该节点):

Dim timeNode As Object
Dim rateDate As String
Set timeNode = xhr.responseXML.SelectSingleNode("//ecb:Cube[@time]")
If Not timeNode Is Nothing Then
  rateDate = timeNode.GetAttribute("time")
  ' 此处可加入日期判断逻辑:比如对比数据库已有日期,决定是否存储后续汇率
  Debug.Print "汇率日期:" & rateDate
End If

完整修改后的代码

Dim xhr As Object, node As Object, timeNode As Object
Dim exchangeRates As Collection
Dim rateDate As String

Set exchangeRates = New Collection

' 发送GET请求获取XML数据
Set xhr = CreateObject("msxml2.xmlhttp.6.0")
xhr.Open "GET", "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml", False
xhr.Send

' 注册默认命名空间前缀
xhr.responseXML.setProperty "SelectionNamespaces", "xmlns:ecb='http://www.ecb.int/vocabulary/2002-08-01/eurofxref'"

' 获取汇率日期
Set timeNode = xhr.responseXML.SelectSingleNode("//ecb:Cube[@time]")
If Not timeNode Is Nothing Then
  rateDate = timeNode.GetAttribute("time")
  Debug.Print "当前汇率日期:" & rateDate
  ' 加入你的日期校验逻辑,比如检查数据库是否已存在该日期数据
End If

' 遍历并存储汇率数据
For Each node In xhr.responseXML.SelectNodes("//ecb:Cube[@rate]")
  exchangeRates.Add Conversion.Val(node.GetAttribute("rate")), node.GetAttribute("currency")
  lb_CurrencySelection.AddItem node.GetAttribute("currency")
Next

' 清理对象
Set xhr = Nothing
Set timeNode = Nothing
Set node = Nothing
Set exchangeRates = Nothing

关键说明

  • 命名空间必须注册:XML的默认命名空间不会被自动识别,SelectNodes/SelectSingleNode必须通过前缀才能匹配到目标节点。
  • 使用SelectSingleNode更高效:每日汇率XML仅包含一个带time属性的Cube节点,无需用SelectNodes遍历。

内容的提问来源于stack exchange,提问作者bot.rubiks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 08:40:33