问题描述
我用erlang语言收到了这些孩子的JSON数据:
{"Time":"2020-08-16T15:28:55","BME680":{"Temperature":29.8,"Humidity":55.5,"Pressure":1003.5,"Gas":422.24},"PressureUnit":"hPa","TempUnit":"C"}
或
{"Time":"2020-08-16T11:39:49","SI7021":{"Temperature":32.4,"Humidity":99.9},"TempUnit":"C"}
我需要为每个JSON数据选择一个值,例如: 根据“ BME680”值
{"Temperature":29.8,"Humidity":54.8,"Pressure":1005.0,"Gas":1513.60}
或 根据“ SI7021”值
{"Temperature":32.4,"Humidity":99.9}
如何用erlang语言完成此任务? 如果比较简单,我需要提取每个JSON数据的第二个值。
解决方法
要将JSON格式解码为Erlang格式的数据(如proplists或maps),可以尝试使用第三方库jiffy,然后可以使用简单的模式匹配,例如:
地图:
1> JSON = "{\"Time\":\"2020-08-17T05:32:09\",\"BME680\":{\"Temperature\":29.6,\"Humidity\":54.6,\"Pressure\":1003.9,\"Gas\":1517.91},\"PressureUnit\":\"hPa\",\"TempUnit\":\"C\"}".
2> Map = jiffy:decode(JSON,[return_maps]).
3> #{<<"BME680">> := BME680} = Map.
4> BME680.
#{<<"Gas">> => 1517.91,<<"Humidity">> => 54.6,<<"Pressure">> => 1003.9,<<"Temperature">> => 29.6}
专家:
1> JSON = "{\"Time\":\"2020-08-17T05:32:09\",\"TempUnit\":\"C\"}".
2> {Proplists} = jiffy:decode(JSON).
3> [BME680] = [V || {K,V} <- Proplists,K == <<"BME680">>].
4> BME680.
{[{<<"Temperature">>,29.6},{<<"Humidity">>,54.6},{<<"Pressure">>,1003.9},{<<"Gas">>,1517.91}]}
,
您可以使用mochiweb项目中的2个模块:
- https://github.com/mochi/mochiweb/blob/master/src/mochijson2.erl
- https://raw.githubusercontent.com/mochi/mochiweb/master/src/mochinum.erl
将它们放在某个文件夹中(例如测试),然后运行erl shell并编译以下文件:
alexei@MacBook-Pro test % erl
Erlang/OTP 23 [erts-11.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe] [dtrace]
Eshell V11.0 (abort with ^G)
1> c("mochijson2.erl").
{ok,mochijson2}
2> c("mochinum.erl").
{ok,mochinum}
将json-as-text解码为json-as-erlang-term:
3> Body = "{\"Time\":\"2020-08-16T15:28:55\",\"BME680\":{\"Temperature\":29.8,\"Humidity\":55.5,\"Pressure\":1003.5,\"Gas\":422.24},\"TempUnit\":\"C\"}".
"{\"Time\":\"2020-08-16T15:28:55\",\"TempUnit\":\"C\"}"
4> {struct,Map} = mochijson2:decode(Body).
{struct,[{<<"Time">>,<<"2020-08-16T15:28:55">>},{<<"BME680">>,{struct,[{<<"Temperature">>,29.8},55.5},1003.5},422.24}]}},{<<"PressureUnit">>,<<"hPa">>},{<<"TempUnit">>,<<"C">>}]}
取回您需要的物品:
5> {struct,Obj1} = proplists:get_value(<<"BME680">>,Map).
{struct,422.24}]}
6> Item1 = proplists:lookup(<<"Temperature">>,Obj1).
{<<"Temperature">>,29.8}
7> Item2 = proplists:lookup(<<"Humidity">>,Obj1).
{<<"Humidity">>,55.5}
然后将erlang术语编码为文本:
8> List = [Item1,Item2].
[{<<"Temperature">>,55.5}]
9> iolist_to_binary(mochijson2:encode({struct,List})).
<<"{\"Temperature\":29.8,\"Humidity\":55.5}">>
mochijson2的文档很短,但是在shell中练习很容易。
,您需要熟悉rebar3,它是erlang的软件包管理器。然后,您可以使用jsx之类的程序包,该程序包使您可以在二进制类型和映射之间进行转换。首先,您需要将调用“ JSON”的内容转换为二进制类型,可能先使用tuple_to_list()
然后使用list_to_binary()
,然后可以使用jsx包将二进制转换为映射,这将使您能够从地图中提取目标值。
这是一个例子:
my.erl:
json_to_map(Bin) ->
jsx:decode(
%%<<"{\"data\": [1,2,3]}">>,Bin,[return_maps]
).
在外壳中:
~/erlang_programs/myapp$ rebar3 compile
===> Verifying dependencies...
===> Compiling myapp
src/my.erl:2: Warning: export_all flag enabled - all functions will be exported
~/erlang_programs/myapp$ rebar3 shell
===> Verifying dependencies...
===> Compiling myapp
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> Bin1 = <<"{\"A\": 100,\"B\":{\"x\": 4,\"y\": [1,3]}}">>.
<<"{\"A\": 100,3]}}">>
2> Bin2 = <<"{\"A\":200,\"C\":{\"a\": 6,\"b\": [3,4,5]}}">>.
<<"{\"A\":200,5]}}">>
3> M1 = my:json_to_map(Bin1).
#{<<"A">> => 100,<<"B">> => #{<<"x">> => 4,<<"y">> => [1,3]}}
4> M2 = my:json_to_map(Bin2).
#{<<"A">> => 200,<<"C">> => #{<<"a">> => 6,<<"b">> => [3,5]}}
5> [V1] = maps:values( maps:without([<<"A">>],M1)).
[#{<<"x">> => 4,3]}]
6> V1.
#{<<"x">> => 4,3]}
7> [V2] = maps:values( maps:without([<<"A">>],M2)).
[#{<<"a">> => 6,5]}]
8> V2.
#{<<"a">> => 6,5]}
9>
,
您好,按照我的建议,如果“正文”等于:是否可以纠正我的以下代码:
"{\"Time\":\"2020-08-17T05:32:09\",\"TempUnit\":\"C\"}"
我的代码
....
eBody = jiffy:decode(<<Body>>),Map = #eBody,#{"BME680" := BME680} = Map,newbody = jiffy:encode(BME680),HTTPOptions = [],Options = [],R = httpc:request(Method,{URL,Header,Type,newbody},HTTPOptions,Options),....
我是erlang的新手。