簡體   English   中英

使用JSON的ERLANG

[英]ERLANG with JSON

我在erlang運行以下命令,

os:cmd("curl -k -X GET http://10.210.12.154:10065/iot/get/task").

它給出了這樣的JSON輸出,

{"data":[
    {"id":1,"task":"Turn on the bulb when the temperature in greater than 28","working_condition":1,"depending_value":"Temperature","action":"123"},
    {"id":2,"task":"Trun on the second bulb when the temperature is greater than 30","working_condition":0,"depending_value":"Temperature","action":"124"}
]}

我想將此數據分類為ID,任務,depending_value,操作。 就像將它們放在桌子上一樣。 我想輕松地找到Id = 1的相關值,工作條件和操作。 我怎樣才能做到這一點?

它給出了這樣的JSON輸出。

 {"data":[{"id":1,"t ... 

高度懷疑。 文檔說os:cmd()返回的字符串不是以{開頭。 還要注意,字符串甚至都不是erlang數據類型,而雙引號是創建list of integers捷徑,並且整數列表在您的情況下並不是很有用。

這里有兩個選擇:

  1. os:cmd()返回的整數列表上調用list_to_binary()list_to_binary()轉換為binary

  2. 代替os:cmd() ,使用erlang http客戶端(如hackney) ,它將以binary返回json。

您想要二進制文件的原因是因為您可以使用jsx之類的erlang json模塊將二進制文件轉換為erlang映射(可能是您想要的?)。

如下所示:

3> Json = <<"{\"data\": [{\"x\": 1, \"y\": 2}, {\"a\": 3, \"b\": 4}] }">>. 
<<"{\"data\": [{\"x\": 1, \"y\": 2}, {\"a\": 3, \"b\": 4}] }">>

4> Map = jsx:decode(Json, [return_maps]).
#{<<"data">> =>
      [#{<<"x">> => 1,<<"y">> => 2},#{<<"a">> => 3,<<"b">> => 4}]}

5> Data = maps:get(<<"data">>, Map).     
[#{<<"x">> => 1,<<"y">> => 2},#{<<"a">> => 3,<<"b">> => 4}]

6> InnerMap1 = hd(Data).   
#{<<"x">> => 1,<<"y">> => 2}

7> maps:get(<<"x">>, InnerMap1).
1

...把他們放在桌子上。 我想輕松地找到Id = 1的相關值,工作條件和操作。

Erlang有各種表實現: etsdetsmnesia 這是一個ets示例:

-module(my).
-compile(export_all).

get_tasks() ->
    Method = get,

    %See description of this awesome website below.
    URL = <<"https://my-json-server.typicode.com/7stud/json_server/db">>,

    Headers = [],
    Payload = <<>>,
    Options = [],

    {ok, 200, _RespHeaders, ClientRef} =
        hackney:request(Method, URL, Headers, Payload, Options),
    {ok, Body} = hackney:body(ClientRef),
    %{ok, Body} = file:read_file('json/json.txt'),  %Or, for testing you can paste the json in a file (without the outer quotes), and read_file() will return a binary.

    Map = jsx:decode(Body, [return_maps]),
    _Tasks = maps:get(<<"data">>, Map).

create_table(TableName, Tuples) ->
    ets:new(TableName, [set, named_table]),
    insert(TableName, Tuples).

insert(_Table, []) ->
    ok;
insert(Table, [Tuple|Tuples]) ->
    #{<<"id">> := Id} = Tuple,
    ets:insert(Table, {Id, Tuple}),
    insert(Table, Tuples).

retrieve_task(TableName, Id) ->
    [{_Id, Task}] = ets:lookup(TableName, Id), 
    Task.

默認情況下,ets set類型表確保插入的元組中的第一個位置是唯一鍵(或者您可以在元組中顯式指定另一個位置作為唯一鍵)。

**如果您有github帳戶,我發現了一個非常酷的網站,它允許您將json文件放置在github上的新存儲庫中,並且該網站會將該文件用作json。 https://my-json-server.typicode.com上進行檢查:

如何

  1. 在GitHub上創建存儲庫(<your-username>/<your-repo>)的存儲庫(<your-username>/<your-repo>)
  2. 在存儲庫中創建一個db.json文件。
  3. 訪問https://my-json-server.typicode.com/ <your-username>/<your-repo>以訪問您的服務器

您可以在代碼中看到我正在使用的url,可以通過單擊提供的服務器頁面上的鏈接並將該url復制到Web瀏覽器的地址欄中來獲得。

在外殼中:

.../myapp$ rebar3 shell
===> Verifying dependencies...
===> Compiling myapp
src/my.erl:2: Warning: export_all flag enabled - all functions will be exported

Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] [kernel-poll:false]
Eshell V9.3  (abort with ^G)

1> ===> The rebar3 shell is a development tool; to deploy applications in production, consider using releases (http://www.rebar3.org/docs/releases) 
===> Booted unicode_util_compat
===> Booted idna
===> Booted mimerl
===> Booted certifi
===> Booted ssl_verify_fun
===> Booted metrics
===> Booted hackney

1> Tasks = my:get_tasks().     
[#{<<"action">> => <<"123">>,
   <<"depending_value">> => <<"Temperature">>,<<"id">> => 1,
   <<"task">> =>
       <<"Turn on the bulb when the temperature in greater than 28">>,
   <<"working_condition">> => 1},
 #{<<"action">> => <<"124">>,
   <<"depending_value">> => <<"Temperature">>,<<"id">> => 2,
   <<"task">> =>
       <<"Trun on the second bulb when the temperature is greater than 30">>,
   <<"working_condition">> => 0}]

2> my:create_table(tasks, Tasks).
ok

3> my:retrieve_task(tasks, 1).   
#{<<"action">> => <<"123">>,
  <<"depending_value">> => <<"Temperature">>,<<"id">> => 1,
  <<"task">> =>
      <<"Turn on the bulb when the temperature in greater than 28">>,
  <<"working_condition">> => 1}

4> my:retrieve_task(tasks, 2).   
#{<<"action">> => <<"124">>,
  <<"depending_value">> => <<"Temperature">>,<<"id">> => 2,
  <<"task">> =>
      <<"Trun on the second bulb when the temperature is greater than 30">>,
  <<"working_condition">> => 0}

5> my:retrieve_task(tasks, 3).
** exception error: no match of right hand side value []
     in function  my:retrieve_task/2 (/Users/7stud/erlang_programs/old/myapp/src/my.erl, line 58)

6> 

請注意,id在其中一行的末尾位於右側。 另外,如果您在Shell中遇到任何錯誤,則Shell將自動重新啟動新進程,並且ets表將被銷毀,因此您必須重新創建它。

rebar.config:

{erl_opts, [debug_info]}.
{deps, [
    {jsx, "2.8.0"},
    {hackney, ".*", {git, "git://github.com/benoitc/hackney.git", {branch, "master"}}}
]}.
{shell, [{apps, [hackney]}]}. % This causes the shell to automatically start the listed apps.  See https://stackoverflow.com/questions/40211752/how-to-get-an-erlang-app-to-run-at-starting-rebar3/45361175#comment95565011_45361175

src / myapp.app.src:

{application, 'myapp',
 [{description, "An OTP application"},
  {vsn, "0.1.0"},
  {registered, []},
  {mod, {'myapp_app', []}},
  {applications,
   [kernel,
    stdlib
   ]},
  {env,[]},
  {modules, []},

  {contributors, []},
  {licenses, []},
  {links, []}
 ]}.

但是,根據rebar3依賴文檔

您應該將每個依賴項添加到您的app或app.src文件中:

因此,我猜src/myapp.app.src應該看起來像這樣:

{application, 'myapp',
 [{description, "An OTP application"},
  {vsn, "0.1.0"},
  {registered, []},
  {mod, {'myapp_app', []}},
  {applications,
   [kernel,
    stdlib,
    jsx,
    hackney
   ]},
  {env,[]},
  {modules, []},

  {contributors, []},
  {licenses, []},
  {links, []}
 ]}.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM