groovy解析xml_使用Groovy访问和解析汇率API

groovy解析xml

我住在加拿大,在其他国家/地区从事很多工作,因此当我记账时,我必须将外币的收入和支出转换为加元。 我过去常常通过辛苦地查询加拿大银行的历史汇率来做到这一点,但去年该银行减少了其支持的货币数量。 我决定使用发布货币汇率历史数据的网站和Java Groovy Apache Groovy (这是一种Java平台的编程语言),寻求一种不同且更实用的解决方案。

我发现了两个外汇历史记录站点,这些站点允许以某种形式对其API进行调用(以JSON返回结果)的方式进行一定程度的免费访问,因此我在Groovy中编写了一个小脚本来解析JSON并返回我需要输入的信息在我的簿记程序中。 这是我的方法。

汇率网站及其API

我发现的第一个站点是Fixer.io ,我非常喜欢。 这是一项免费服务,可从欧洲中央银行访问数据。 该API简单易用。 例如,如果我想要加元和印度卢比的汇率,请使用以下URL:

https://api.fixer.io/latest?symbols=CAD,INR

当我对本文进行查询时,它返回以下JSON:



   
   
{
  "base":"EUR",
  "date":"2018-02-15",
  "rates":{"CAD":1.5604,"INR":79.849}
}

这表明,2018年2月15日,购买1欧元需要1.5604加元,购买1欧元需要79.849印度卢比。 要弄清楚购买1加元需要多少印度卢比,只需将79.849除以1.5604,得出每加元51.172印度卢比。 有什么会更容易?

更好的是,Fixer.io是开源的,是根据MIT许可证发布的,并且该代码可在GitHub上获得

Fixer.io满足了我将印度卢比转换为加元的需要,但不幸的是,它没有为智利比索提供解决方案,因为欧洲中央银行的基本数据仅涵盖“ 32个”货币。

为了获得有关智利比索的信息,我最后选择了Currencylayer ,(目前)提供168种货币的数据。 Currencylayer要求注册并为其更有价值的产品和复杂的操作收取费用,但是美元与167种其他货币之间的基本历史汇率转换是免费的。 由于覆盖面广,我使用Currencylayer撰写了这篇文章。

在Currencylayer上注册为用户提供了一个密钥,该密钥可以授予对所选服务层的访问权限。 假设键为K ,则URL如:

http://apilayer.net/api/historical?access_key=K&date=2018-01-01&currencies=CAD,EUR&format=1

将返回以下JSON:



   
   
{
  "success":true,
  "terms":"https:\/\/currencylayer.com\/terms",
  "privacy":"https:\/\/currencylayer.com\/privacy",
  "historical":true,
  "date":"2018-01-01",
  "timestamp":1514851199,
  "source":"USD",
  "quotes":{
    "USDCAD":1.25551,
    "USDEUR":0.832296
  }
}

使用Groovy访问API并解析JSON结果

Groovy提供了一些简洁的工具来处理URL,数据流和JSON。

从JSON末尾开始,有JSON slurper及其方便的parse()方法。 JSON slurper parse方法的一种形式将流作为参数。

这很方便,因为从URL端开始,我们可以使用其newInputStream()方法在URL上打开流

假设我们在一个名为urlString的Groovy字符串变量中构建了URL字符串,即API调用,我们可以打开URL,读取生成的流,并使用以下Groovy代码解析JSON:



   
   
def result = (new JsonSlurper()).parse(
        new InputStreamReader(
                (new URL(urlString)).newInputStream()
        )
)

Groovy变量result是一个映射(即一组键值对),看起来像这样:



   
   
[success:true, terms:https://currencylayer.com/terms,
privacy:https://currencylayer.com/privacy, historical:true,
date:2018-01-01, timestamp:1514851199, source:USD, quotes:
[USDCAD:1.25551, USDEUR:0.832296]]

该映射与上面显示的原始JSON完全对应。 例如,关键date的值是2018-01-01

Groovy允许我们通过以下方式访问分配给date键的值:


result['date'] 

要么


result.date 

两者都将返回值2018-01-01

请注意,关键引号本身就是指具有两个键的地图:一个给出美元和加元之间的转换,另一个给出美元与另一种感兴趣的货币之间的转换。 在上述情况下,可以通过以下方式访问它们



   
   
result['quotes']['USDCAD'] and
result['quotes']['USDEUR']

要么



   
   
result.quotes.USDCAD and
result.quotes.USDEUR.

使用后一种格式,并假设原始金额在Groovy变量amtOrig ,加元金额可以计算为:


def amtCAD = amtOrig / result.quotes.USDEUR * result.quotes.USDCAD 

例如,如果我需要转换通过DFW机场时产生的美元支出,则公式更简单:


def amtCAD = amtOrig * result.quotes.USDCAD 

真的就是全部。

(几乎)工作脚本

让我们将其转换为可运行的Groovy脚本。 我们将从命令行获取参数并进行检查。 然后,如果一切正常,我们将构建URL字符串,调用API,并以地图格式获取结果。 最后,我们将分解结果图并计算交换。 这是脚本:



   
   
import groovy.json.JsonSlurper

// Check to make sure arguments are correct and print usage if not

if (args.size() != 3) {
    System.err.println "usage: groovy fx.groovy yyyy-mm-dd amount currency-code"
    System.exit(1)
}

// Check arguments for formatting and reasonable values

String dateString = args[0]
if (!(dateString ==~ /(19\d\d|2[01]\d\d)\-(0[1-9]|1[012])\-([012]\d|3[01])/)) { 1
    System.err.println "fx.groovy date $dateString not in format yyyy-mm-dd"
    System.exit(1)
}

String amountString = args[1]
if (!(amountString ==~ /\d+(\.\d+)?/)) { 1
    System.err.println "fx.groovy amount $amountString not numeric"
    System.exit(1)
}

String currencyCode = args[2]
if (!(currencyCode ==~ /[A-Z][A-Z][A-Z]/)) { 1
    System.err.println "fx.groovy currency-code $currencyCode not three capital letters, e.g. USD,CAD,EUR,GBP"
    System.exit(1)
}

// Our free license will only convert through USD so we adjust the currency list
// according to whether the original currency was USD or something else

String currencyCodeList = currencyCode == 'USD' ? 'CAD' : "CAD,${currencyCode}" 2

// The access key code given during site signup

String accKey = 'a5bd4434d2299ecb3612ad297402481c' 3

// Build the URL string for the API call, get the JSON and parse it

String urlString = "http://apilayer.net/api/historical?access_key=$accKey&date=${dateString}&currencies=${currencyCodeList}&format=1" 2

def result = (new JsonSlurper()).parse(new InputStreamReader((new URL(urlString)).newInputStream()))

// Pick apart the values returned and compute the exchange info

BigDecimal amtOrig = new BigDecimal(amountString) 4
if (result.quotes.size() > 1) {
    String toUSDString = 'USD' + currencyCode
    BigDecimal amtCAD = amtOrig / result.quotes[toUSDString] * 5
        result.quotes.USDCAD
    println "$amtOrig $currencyCode toUSD ${result.quotes[toUSDString]} toCAD ${result.quotes.USDCAD} $amtCAD" 2
} else {
    BigDecimal amtCAD = amtOrig * result.quotes.USDCAD
    println "$amtOrig $currencyCode toCAD ${result.quotes.USDCAD} $amtCAD" 2
}

一些评论:

  1. 这些是正则表达式模式匹配。 是的,我本可以使用try... catch块。
  2. 表示法... ${foo}...在Groovy中称为Gstring; ${}被求值,然后该值将其替换为最终字符串。
  3. 那不是我的访问密钥! 但是看起来有点像。
  4. 我使用BigDecimal而不是double来进行计算。
  5. 我正在使用[toUSDString]访问值; 这是因为toUSDString是变量,而不是常量字符串。
  6. 长长的线有些缠绕。 对于那个很抱歉!

如果您没有经常使用Groovy,上面的某些内容可能看起来有些不可思议,但实际上并非如此。 我希望这会鼓励进一步的学习!

请注意,以美元为基础的人们不必进行中间计算。

最后的警告提示:这些和其他历史汇率是指示性的,通常根据其他数字的平均值计算得出。 因此,如果在2018年2月15日花费1,623捷克克朗购买100欧元,但Fixer.io在该日期为您提供了25.370捷克克朗对欧元的汇率,这不是错误! 您可能在其他金融机构支付了不同的金额。

翻译自: https://opensource.com/article/18/3/groovy-calculate-foreign-exchange

groovy解析xml

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值