0

我想出了如何使用钢筋。我正在尝试使用 jsx(jiffy 在 Windows 上无法正常工作)来解析我使用 openexchangerates.org API 获得的 json,但我什至无法弄清楚如何正确利用 Erlang 的广泛二进制功能来解包获得的 JSON 元组。使用以下代码片段,我设法获得了一个包含我需要的所有数据的元组:

-module(currency).
-export([start/0]).

start() -> 
    URL = "http://openexchangerates.org",
    Endpoint = "/api/latest.json?app_id=<myprivateid>",
    X = string:concat(URL, Endpoint),
    % io:format("~p~n",[X]).
    inets:start(),
    {ok, Req} = httpc:request(X),
    Req.

这是获得的响应:

9> currency:start().
{{"HTTP/1.1",200,"OK"},
 [{"cache-control","public"},
  {"connection","close"},
  {"date","Fri, 15 Aug 2014 01:28:06 GMT"},
  {"etag","\"d9ad180d4af1caaedab6e622ec0a8a70\""},
  {"server","Apache"},
  {"content-length","4370"},
  {"content-type","application/json; charset=utf-8"},
  {"last-modified","Fri, 15 Aug 2014 01:00:56 GMT"},
  {"access-control-allow-origin","*"}],
 "{\n  \"disclaimer\": \"Exchange rates are provided for informational purposes only, and do not constitute financial advice of any kind. Although every attempt is made to ensure quality, NO guarantees are given whatsoever of accuracy, validity, availability, or fitness for any purpose - please use at your own risk. All usage is subject to your acceptance of the Terms and Conditions of Service, available at: https://openexchangerates.org/terms/\",\n  \"license\": \"Data sourced from various providers with public-facing APIs; copyright may apply; resale is prohibited; no warranties given of any kind. Bitcoin data provided by http://coindesk.com. All usage is subject to your acceptance of the License Agreement available at: https://openexchangerates.org/license/\",\n  \"timestamp\": 1408064456,\n  \"base\": \"USD\",\n  \"rates\": {\n    \"AED\": 3.673128,\n    \"AFN\": 56.479925,\n    \"ALL\": 104.147599,\n    \"AMD\": 413.859001,\n    \"ANG\": 1.789,\n    \"AOA\": 97.913074,\n    \"ARS\": 8.274908,\n    \"AUD\": 1.073302,\n    \"AWG\": 1.79005,\n    \"AZN\": 0.783933,\n    \"BAM\": 1.46437,\n    \"BBD\": 2,\n    \"BDT\": 77.478631,\n    \"BGN\": 1.464338,\n    \"BHD\": 0.377041,\n    \"BIF\": 1546.956667,\n    \"BMD\": 1,\n    \"BND\": 1.247024,\n    \"BOB\": 6.91391,\n    \"BRL\": 2.269422,\n    \"BSD\": 1,\n    \"BTC\": 0.0019571961,\n    \"BTN\": 60.843812,\n    \"BWP\": 8.833083,\n    \"BYR\": 10385.016667,\n    \"BZD\": 1.99597,\n    \"CAD\": 1.0906,\n    \"CDF\": 924.311667,\n    \"CHF\": 0.906799,\n    \"CLF\": 0.02399,\n    \"CLP\": 577.521099,\n    \"CNY\": 6.153677,\n    \"COP\": 1880.690016,\n    \"CRC\": 540.082202,\n    \"CUP\": 1.000688,\n    \"CVE\": 82.102201,\n    \"CZK\": 20.81766,\n    \"DJF\": 178.76812,\n    \"DKK\": 5.579046,\n    \"DOP\": 43.43789,\n    \"DZD\": 79.8973,\n    \"EEK\": 11.70595,\n    \"EGP\": 7.151305,\n    \"ERN\": 15.062575,\n    \"ETB\": 19.83205,\n    \"EUR\": 0.748385,\n    \"FJD\": 1.85028,\n    \"FKP\": 0.599315,\n    \"GBP\": 0.599315,\n    \"GEL\": 1.74167,\n    \"GGP\": 0.599315,\n    \"GHS\": 3.735499,\n    \"GIP\": 0.599315,\n    \"GMD\": 39.73668,\n    \"GNF\": 6995.309935,\n    \"GTQ\": 7.839405,\n    \"GYD\": 205.351249,\n    \"HKD\": 7.750863,\n    \"HNL\": 21.04854,\n    \"HRK\": 5.708371,\n    \"HTG\": 44.66625,\n    \"HUF\": 233.847801,\n    \"IDR\": 11682.083333,\n    \"ILS\": 3.471749,\n    \"IMP\": 0.599315,\n    \"INR\": 60.81923,\n    \"IQD\": 1178.211753,\n    \"IRR\": 26354,\n    \"ISK\": 115.976,\n    \"JEP\": 0.599315,\n    \"JMD\": 112.604801,\n    \"JOD\": 0.707578,\n    \"JPY\": 102.501401,\n    \"KES\": 88.106539,\n    \"KGS\": 51.96,\n    \"KHR\": 4056.578416,\n    \"KMF\": 368.149,\n    \"KPW\": 900,\n    \"KRW\": 1021.166657,\n    \"KWD\": 0.283537,\n    \"KYD\": 0.826373,\n    \"KZT\": 182.076001,\n    \"LAK\": 8049.834935,\n    \"LBP\": 1509.068333,\n    \"LKR\": 130.184301,\n    \"LRD\": 91.49085,\n    \"LSL\": 10.56165,\n    \"LTL\": 2.583284,\n    \"LVL\": 0.521303,\n    \"LYD\": 1.244127,\n    \"MAD\": 8.372529,\n    \"MDL\": 13.7178,\n    \"MGA\": 2495.605,\n    \"MKD\": 45.99967,\n    \"MMK\": 972.1784,\n    \"MNT\": 1884.666667,\n    \"MOP\": 7.986251,\n    \"MRO\": 292.0081,\n    \"MTL\": 0.683602,\n    \"MUR\": 30.61708,\n    \"MVR\": 15.37833,\n    \"MWK\": 392.9201,\n    \"MXN\": 13.07888,\n    \"MYR\": 3.175156,\n    \"MZN\": 30.3522,\n    \"NAD\": 10.56145,\n    \"NGN\": 162.303701,\n    \"NIO\": 26.07651,\n    \"NOK\": 6.157432,\n    \"NPR\": 97.66846,\n    \"NZD\": 1.179688,\n    \"OMR\": 0.38501,\n    \"PAB\": 1,\n    \"PEN\": 2.795018,\n    \"PGK\": 2.464545,\n    \"PHP\": 43.66429,\n    \"PKR\": 99.5662,\n    \"PLN\": 3.126223,\n    \"PYG\": 4272.421673,\n    \"QAR\": 3.641137,\n    \"RON\": 3.320192,\n    \"RSD\": 87.82784,\n    \"RUB\": 36.00216,\n    \"RWF\": 690.269,\n    \"SAR\": 3.750523,\n    \"SBD\": 7.269337,\n    \"SCR\": 12.40801,\n    \"SDG\": 5.699103,\n    \"SEK\": 6.86018,\n    \"SGD\": 1.246263,\n    \"SHP\": 0.599315,\n    \"SLL\": 4372.166667,\n    \"SOS\": 841.5678,\n    \"SRD\": 3.275,\n    \"STD\": 18316.816667,\n    \"SVC\": 8.745567,\n    \"SYP\": 150.751249,\n    \"SZL\": 10.56279,\n    \"THB\": 31.86192,\n    \"TJS\": 4.9856,\n    \"TMT\": 2.8501,\n    \"TND\": 1.719658,\n    \"TOP\": 1.8861,\n    \"TRY\": 2.15338,\n    \"TTD\": 6.343484,\n    \"TWD\": 30.00481,\n    \"TZS\": 1661.865,\n    \"UAH\": 13.02466,\n    \"UGX\": 2614.28,\n    \"USD\": 1,\n    \"UYU\": 23.70693,\n    \"UZS\": 2337.106637,\n    \"VEF\": 6.295009,\n    \"VND\": 21191.15,\n    \"VUV\": 94.6,\n    \"WST\": 2.301222,\n    \"XAF\": 491.286739,\n    \"XAG\": 0.05031657,\n    \"XAU\": 0.00076203,\n    \"XCD\": 2.70154,\n    \"XDR\": 0.654135,\n    \"XOF\": 491.394602,\n    \"XPF\": 89.414091,\n    \"YER\": 214.985901,\n    \"ZAR\": 10.55678,\n    \"ZMK\": 5253.075255,\n    \"ZMW\": 6.169833,\n    \"ZWL\": 322.355006\n  }\n}"}

我不明白为什么这段代码不起作用:

X = "Arthur".
B = <<X>>.

JSX 允许很多解析功能,但前提是我有一个二进制文件作为我的 JSON 表示,并且我从货币 API 获得的这个 JSON 是一个元组中的字符串......我有点迷失在哪里开始研究。使用模式匹配解包元组据说非常简单(我已经完成了一些 Prolog 编程,我可以看到 erlang 具有类似的行为)但是是否有另一种更好的、适合 Erlang 的方法来获取 JSON 的“速率”部分我收到作为回应?

谢谢!我正在开发一个很酷的网络应用程序来学习 erlang,这是一个很好的第一步。我有三本 Erlang 书籍,我正在努力阅读它们,但问题是我希望尽早获得尽可能多的实用知识。我喜欢这种语言,但我想尽快打下坚实的基础。

谢谢!

4

2 回答 2

0

我发现了我的问题。

所以首先,我没有想到简单地计算元组中有多少元素是多么简单。话虽如此,我意识到只有三个。

所以我需要的线路是

{A,B,C} = Req.

之后,我只想查看最后一个(C,JSON 有效负载),它是一个字符串。我通过另一个来源(不要忽视你告诉我的,凯!)发现你需要使用列表函数,因为字符串和只是 ASCII 范围内的整数列表(我认为),在这种情况下是 list_to_binary。

一旦我使用了这一行: D = list_to_binary(C),随后 E = jsx:decode(D),我得到了这个输出:

[{<<"disclaimer">>,
  <<"Exchange rates are provided for infor
 attempt is made to ensure quality, NO gua
se - please use at your own risk. All usag
s://openexchangerates.org/terms/">>},
 {<<"license">>,
  <<"Data sourced from various providers w
any kind. Bitcoin data provided by http://
t: https://openexchangerates.org/license/"
 {<<"timestamp">>,1408068012},
 {<<"base">>,<<"USD">>},
 {<<"rates">>,
  [{<<"AED">>,3.673128},
   {<<"AFN">>,56.479925},
   {<<"ALL">>,104.1526},
   {<<"AMD">>,413.859001},
   {<<"ANG">>,1.789},
   {<<"AOA">>,97.913949},
   {<<"ARS">>,8.274608},
   {<<"AUD">>,1.073236},
   {<<"AWG">>,1.79005},
   {<<"AZN">>,0.783933},
   {<<"BAM">>,1.46437},
   {<<"BBD">>,2},
   {<<"BDT">>,77.478631},
   {<<"BGN">>,1.464358},
   {<<"BHD">>,0.377041},
   {<<"BIF">>,1546.956667},
   {<<"BMD">>,1},
   {<<"BND">>,1.246774},
   {<<"BOB">>,6.91391},
   {<<"BRL">>,2.269462},
   {<<"BSD">>,1},
   {<<"BTC">>,0.0019393375},
   {<<"BTN">>,60.843812},
   {<<"BWP">>,8.833083},
   {<<"BYR">>,10385.016667},
   {<<"BZD">>,1.99597},
   {<<"CAD">>,1.090486},
   {<<"CDF">>,924.311667},
   {<<"CHF">>,0.906833},
   {<<"CLF">>,0.02399},
   {<<"CLP">>,577.521099},
   {<<"CNY">>,6.151637},
   {<<"COP">>,1880.690016},
   {<<"CRC">>,540.082202},
   {<<"CUP">>,1.000688},
   {<<"CVE">>,82.049699},
   {<<"CZK">>,20.818},
   {<<"DJF">>,179.084119},
   {<<"DKK">>,5.579049},
   {<<"DOP">>,43.43789},
   {<<"DZD">>,79.8641},
   {<<"EEK">>,11.7064},
   {<<"EGP">>,7.150475},
   {<<"ERN">>,15.062575},
   {<<"ETB">>,19.83205},
   {<<"EUR">>,0.748419},
   {<<"FJD">>,1.850441},
   {<<"FKP">>,0.599402},
   {<<"GBP">>,0.599402},
   {<<"GEL">>,1.74167},
   {<<"GGP">>,0.599402},
   {<<"GHS">>,3.735499},
   {<<"GIP">>,0.599402},
   {<<"GMD">>,39.73668},
   {<<"GNF">>,6995.309935},
   {<<"GTQ">>,7.839405},
   {<<"GYD">>,205.351249},
   {<<"HKD">>,7.750754},
   {<<"HNL">>,21.04854},
   {<<"HRK">>,5.708511},
   {<<"HTG">>,44.66625},
   {<<"HUF">>,233.8448},
   {<<"IDR">>,11685.75},
   {<<"ILS">>,3.471469},
   {<<"IMP">>,0.599402},
   {<<"INR">>,60.82523},
   {<<"IQD">>,1178.211753},
   {<<"IRR">>,26355.666667},
   {<<"ISK">>,115.96},
   {<<"JEP">>,0.599402},
   {<<"JMD">>,112.604801},
   {<<"JOD">>,0.707778},
   {<<"JPY">>,102.495401},
   {<<"KES">>,88.107639},
   {<<"KGS">>,51.991},
   {<<"KHR">>,4056.578416},
   {<<"KMF">>,368.142141},
   {<<"KPW">>,900},
   {<<"KRW">>,1021.353328},
   {<<"KWD">>,0.283537},
   {<<"KYD">>,0.826373},
   {<<"KZT">>,182.076001},
   {<<"LAK">>,8049.834935},
   {<<"LBP">>,1509.068333},
   {<<"LKR">>,130.184301},
   {<<"LRD">>,91.49085},
   {<<"LSL">>,10.56165},
   {<<"LTL">>,2.583364},
   {<<"LVL">>,0.521328},
   {<<"LYD">>,1.244147},
   {<<"MAD">>,8.372619},
   {<<"MDL">>,13.7178},
   {<<"MGA">>,2495.605},
   {<<"MKD">>,46.00037},
   {<<"MMK">>,972.1784},
   {<<"MNT">>,1885},
   {<<"MOP">>,7.986291},
   {<<"MRO">>,292.0081},
   {<<"MTL">>,0.683738},
   {<<"MUR">>,30.61748},
   {<<"MVR">>,15.37833},
   {<<"MWK">>,392.9201},
   {<<"MXN">>,13.07883},
   {<<"MYR">>,3.175406},
   {<<"MZN">>,30.3272},
   {<<"NAD">>,10.56145},
   {<<"NGN">>,162.303701},
   {<<"NIO">>,26.07651},
   {<<"NOK">>,6.156902},
   {<<"NPR">>,97.66846},
   {<<"NZD">>,1.179692},
   {<<"OMR">>,0.38501},
   {<<"PAB">>,1},
   {<<"PEN">>,2.795018},
   {<<"PGK">>,2.464545},
   {<<"PHP">>,43.68439},
   {<<"PKR">>,99.5642},
   {<<"PLN">>,3.126203},
   {<<"PYG">>,4272.421673},
   {<<"QAR">>,3.641297},
   {<<"RON">>,3.319212},
   {<<"RSD">>,87.8205},
   {<<"RUB">>,36.00206},
   {<<"RWF">>,690.088},
   {<<"SAR">>,3.750583},
   {<<"SBD">>,7.258136},
   {<<"SCR">>,12.40829},
   {<<"SDG">>,5.697837},
   {<<"SEK">>,6.857347},
   {<<"SGD">>,1.246447},
   {<<"SHP">>,0.599402},
   {<<"SLL">>,4360},
   {<<"SOS">>,841.5678},
   {<<"SRD">>,3.275},
   {<<"STD">>,18322.733333},
   {<<"SVC">>,8.745567},
   {<<"SYP">>,150.793749},
   {<<"SZL">>,10.56279},
   {<<"THB">>,31.87122},
   {<<"TJS">>,4.985575},
   {<<"TMT">>,2.8501},
   {<<"TND">>,1.719698},
   {<<"TOP">>,1.889033},
   {<<"TRY">>,2.15342},
   {<<"TTD">>,6.343484},
   {<<"TWD">>,29.99281},
   {<<"TZS">>,1661.865},
   {<<"UAH">>,13.02466},
   {<<"UGX">>,2614.28},
   {<<"USD">>,1},
   {<<"UYU">>,23.70693},
   {<<"UZS">>,2337.773304},
   {<<"VEF">>,6.295009},
   {<<"VND">>,21191.15},
   {<<"VUV">>,94.4875},
   {<<"WST">>,2.301222},
   {<<"XAF">>,491.283058},
   {<<"XAG">>,0.05031404},
   {<<"XAU">>,7.6211e-4},
   {<<"XCD">>,2.70154},
   {<<"XDR">>,0.654135},
   {<<"XOF">>,491.394602},
   {<<"XPF">>,89.416091},
   {<<"YER">>,214.985901},
   {<<"ZAR">>,10.55649},
   {<<"ZMK">>,5252.024745},
   {<<"ZMW">>,6.169833},
   {<<"ZWL">>,322.355006}]}]
ok

所以这更接近我想要的,但我如何轻松提取特定货币?以 ZWL 为例。

于 2014-08-15T02:18:57.377 回答
0
get_currencies() ->    
    URL = "http://openexchangerates.org",
    Endpoint = "/api/latest.json?app_id=<myprivateid>",
    X = string:concat(URL, Endpoint),
    % io:format("~p~n",[X]).
    inets:start(),
    {ok, {_,_,R}} = httpc:request(X),
    E = jsx:decode(lists_to_binary(R)),
    Base = proplists:get_value(<<"base">>,E),
    Sec = proplists:get_value(<<"timestamp">>,E),
    {Days,Time} = calendar:seconds_to_daystime(Sec),
    Date = calendar:gregorian_days_to_date(Days+719528),
    Currencies = proplists:get_value(<<"rates">>,E),
    fun(C) -> V = proplists:get_value(C,Currencies),
                  {change,Date,Time,Base,C,V}
    end.

在您的代码中的某处:

GC = get_currencies(), %% you can store GC in an ets, a server state...
%% but don't forget to refresh it :o)

并在以后使用

{change,D,T,B,C,V} = GC(<<"ZWL">>),
%% should return {change,{2014,8,15},{2,0,12},<<"USD">>,<<"ZWL">>,322.355006}

[编辑]

当我使用 jsx 等外部应用程序(使用 rebar 本身)时,我也使用 rebar 及其依赖机制来创建自己的应用程序,在我看来这是最方便的方式。(在其他情况下,我也使用钢筋:o)

然后我使用 OTP 行为(应用程序、主管、gen_server ...)构建我的应用程序。需要编写很多模块,但其中一些非常非常短(应用程序和主管),它们有助于应用程序结构(如果您不熟悉,请参阅什么是 OTP )。

在您的情况下,我的第一个想法是拥有一个生成服务器,该服务器在其状态下构建和存储 GC 匿名函数,每次它收到诸如 的强制转换消息时update_currencies,并在每次收到诸如{get_change,Cur}(和如果 GC 未定义或过时,可能会刷新它)。

您还必须决定在哪里管理错误 -它可能无处可去:如果 gen_server 除了回答这个货币查询之外什么都不做:如果出现错误,它将崩溃并由其主管重新启动- 因为这段代码有很多与外部世界的接口,因此会出现许多故障(无法访问 Internet,站点的答案结构发生变化,用户的货币请求不正确......)

于 2014-08-15T06:44:57.477 回答