如何在Erlang中手动创建JSON字符串
我不熟悉Erlang,注意到没有本地函数可以从列表中创建json字符串(或者是否有?)。我使用此方法在Erlang中创建json字符串,但不知道它是否会出现故障 以下是我的方法的一个示例:如何在Erlang中手动创建JSON字符串,json,erlang,Json,Erlang,我不熟悉Erlang,注意到没有本地函数可以从列表中创建json字符串(或者是否有?)。我使用此方法在Erlang中创建json字符串,但不知道它是否会出现故障 以下是我的方法的一个示例: -module(index). -export([test/0]). test() -> Ma = "Hello World", Mb = "Hello Erlang", A = "{\"Messages\" : [
-module(index).
-export([test/0]).
test() ->
Ma = "Hello World", Mb = "Hello Erlang",
A = "{\"Messages\" : [\"" ++ Ma ++ "\", \""++Mb++"\"], \"Usernames\" : [\"Username1\", \"Username2\"]}",
A.
结果是:
388> test().
"{\"Messages\" : [\"Hello World\", \"Hello Erlang\"], \"Usernames\" : [\"Username1\", \"Username2\"]}"
389>
我认为这是预期的结果,但当包含特殊字符时,如:,&/\“?
,该方法是否有可能出现故障
我应该采取哪些预防措施来增强此方法?如果
Ma
或Mb
包含双引号或任何控制字符,则从字符串到JSON的解析将失败。此解析可能永远不会在Erlang中发生,因为Erlang没有内置的字符串到JSON的转换
使用二进制文件(
)是个好主意,因为列表会消耗更多的资源
我们使用的是,它是作为一个组件实现的,因此速度相当快,并且允许这样的文档构造:
jiffy:decode(<<"{\"foo\": \"bar\"}">>).
{[{<<"foo">>,<<"bar">>}]}
Doc = {[{foo, [<<"bing">>, 2.3, true]}]}.
{[{foo,[<<"bing">>,2.3,true]}]}
jiffy:encode(Doc).
<<"{\"foo\":[\"bing\",2.3,true]}">>
jiffy:decode()。
{[{,}]}
Doc={[{foo,[,2.3,true]}}。
{[{foo,[,2.3,true]}}
jiffy:编码(Doc)。
像一个
-define(JSON_包装器(Proplist),{Proplist})。
-来自_列表(json_proplist())->object()的规范。
从_列表([])->new();
从\u列表(L)何时是\u列表(L)->?JSON\u包装器(L)。
-规范为二进制(atom()| string()| binary()| integer()| float()| pid()| iolist())->binary()。
to_binary(X)当_float(X)->to_binary(mochinum:digits(X));
to_binary(X)当是_integer(X)->list_to_binary(integer_to_list(X));
to_binary(X)何时为_atom(X)->list_to_binary(atom_to_list(X));
to_binary(X)当是_list(X)->iolist_to_binary(X);
to_binary(X)当_pid(X)->to_binary(pid_to_list(X));
当_binary(X)->X时,到_binary(X)。
-从_proplist(any())->object()中指定递归_。
递归_-from_-proplist([])->new();
递归\u从\u proplist(List)当是\u List(List)->
案例列表:全部(fun是\u整数/1,列表)
'正确'->列表;
“假”->
from_list([{to_binary(K),recursive_from_proplist(V)}
||{K,V}其他。
这对我很有用
test()->
Ma = "Hello World", Mb = "Hello Erlang",
A = "{\"Messages\" : {{\"Ma\":\"" ++ Ma ++ "\"}, {\"Mb\":\""++Mb++"\"}}, {\"Usernames\" : {\"Username1\":\"usrname1\"}, {\"Username2\":\"usrname2\"}}",
io:format("~s~n",[A]).
输出
10> io:format("~s~n",[A]).
{"Messages" : {{"Ma":Hello World"}, {"Mb":Hello Erlang"}}, {"Usernames" : {"Username1":"usrname1"}, {"Username2":"usrname2"}}
ok
或者使用github上的许多库之一将erlang术语转换为json。我也遇到了同样的问题,到处搜索,最后找到了自己的方法。这纯粹是为人们指明了正确的方向,让他们自己找到解决方案。注意:我尝试了jiffy,但由于我使用的是rebar3,它目前不兼容。 我使用MS sql server,因此我使用Erlang odbc模块: odbc:sql\u查询/2返回
{selected,Columns,Results}
从这里,我可以获取列
,这是一个字符串列表&结果,一个以元组表示的行列表,然后创建一些函数来输出有效的Erlang代码,以便能够基于许多因素正确地序列化为Json。下面是完整的代码:
进行初始查询:
Sql = "SELECT * FROM alloys;",
Ref = connect(),
case odbc:sql_query(Ref, Sql) of
{selected, Columns, Results} ->
set_json_from_sql(Columns, Results, []);
{error, Reason} ->
{error, Reason}
end.
然后输入函数是set\u json\u from\u sql/3
,它调用以下函数:
format_by_type(Item) ->
if
is_list(Item) -> list_to_binary(io_lib:format("~s", [Item]));
is_integer(Item) -> Item;
is_boolean(Item) -> io_lib:format("~a", [Item]);
is_atom(Item) -> Item
end.
json_by_type([H], [Hc], Data) ->
NewH = format_by_type(H),
set_json_flatten(Data, Hc, NewH);
json_by_type([H|T], [Hc|Tc], Data) ->
NewH = format_by_type(H),
NewData = set_json_flatten(Data, Hc, NewH),
json_by_type(T, Tc, NewData).
set_json_flatten(Data, Column, Row) ->
ResTuple = {list_to_binary(Column), Row},
lists:flatten(Data, [ResTuple]).
set_json_from_sql([], [], Data) -> jsone:encode([{<<"data">>, lists:reverse(Data)}]);
set_json_from_sql(Columns, [H], Data) ->
NewData = set_json_merge(H, Columns, Data),
set_json_from_sql([], [], NewData);
set_json_from_sql(Columns, [H|T], Data) ->
NewData = set_json_merge(H, Columns, Data),
set_json_from_sql(Columns, T, NewData).
set_json_merge(Row, Columns, Data) ->
TupleRow = json_by_type(tuple_to_list(Row), Columns, []),
lists:append([TupleRow], Data).
按类型(项目)设置格式->
如果
is_list(Item)->list_to_binary(io_lib:format(“~s”,[Item]);
is_整数(项目)->项目;
is_boolean(Item)->io_lib:format(“~a”,[Item]);
是原子(项目)->项目吗
结束。
json按类型([H],[Hc],数据)->
NewH=按类型(H)格式化,
设置json扁平化(数据、Hc、NewH);
json|u按_类型([H|T],[Hc|Tc],数据)->
NewH=按类型(H)格式化,
NewData=set_json_flant(数据,Hc,NewH),
json_按_类型(T、Tc、NewData)。
设置json扁平化(数据、列、行)->
ResTuple={list_to_binary(Column),Row},
列表:展平(数据,[ResTuple])。
设置_json_from_sql([],[],Data)->jsone:encode([{,list:reverse(Data)}]);
从sql设置json(列[H],数据)->
NewData=set_json_merge(H、列、数据),
从_sql([],[],NewData)设置_json_;
从sql(列[H | T],数据)中设置json->
NewData=set_json_merge(H、列、数据),
从sql(列、T、NewData)中设置json。
设置json合并(行、列、数据)->
TupleRow=json_,按_类型(元组到_列表(行),列,[]),
列表:追加([TupleRow],数据)。
因此,set\u-json\u from\u-sql/3
在匹配set\u-json\u from\u-sql([],[],Data)
后为您提供json输出
这里的要点是,您需要为st调用list\u to\u binary/1
format_by_type(Item) ->
if
is_list(Item) -> list_to_binary(io_lib:format("~s", [Item]));
is_integer(Item) -> Item;
is_boolean(Item) -> io_lib:format("~a", [Item]);
is_atom(Item) -> Item
end.
json_by_type([H], [Hc], Data) ->
NewH = format_by_type(H),
set_json_flatten(Data, Hc, NewH);
json_by_type([H|T], [Hc|Tc], Data) ->
NewH = format_by_type(H),
NewData = set_json_flatten(Data, Hc, NewH),
json_by_type(T, Tc, NewData).
set_json_flatten(Data, Column, Row) ->
ResTuple = {list_to_binary(Column), Row},
lists:flatten(Data, [ResTuple]).
set_json_from_sql([], [], Data) -> jsone:encode([{<<"data">>, lists:reverse(Data)}]);
set_json_from_sql(Columns, [H], Data) ->
NewData = set_json_merge(H, Columns, Data),
set_json_from_sql([], [], NewData);
set_json_from_sql(Columns, [H|T], Data) ->
NewData = set_json_merge(H, Columns, Data),
set_json_from_sql(Columns, T, NewData).
set_json_merge(Row, Columns, Data) ->
TupleRow = json_by_type(tuple_to_list(Row), Columns, []),
lists:append([TupleRow], Data).