简体   繁体   English

在Erlang中使用mochijson2解码JSON

[英]Decode JSON with mochijson2 in Erlang

I have a var that has some JSON data: 我有一个包含一些JSON数据的var:

A = <<"{\"job\": {\"id\": \"1\"}}">>. 

Using mochijson2, I decode the data: 使用mochijson2,我解码数据:

 Struct = mochijson2:decode(A). 

And now I have this: 现在我有了这个:

{struct,[{<<"job">>,{struct,[{<<"id">>,<<"1">>}]}}]}

I am trying to read (for example), "job" or "id". 我想读(例如),“工作”或“id”。

I tried using struct.get_value but it doesn't seem to work. 我尝试使用struct.get_value但它似乎不起作用。

Any ideas? 有任何想法吗?

The data is in {struct, proplist()} format, so here's what you do: 数据采用{struct,proplist()}格式,所以这就是你要做的:

{struct, JsonData} = Struct,
{struct, Job} = proplists:get_value(<<"job">>, JsonData),
Id = proplists:get_value(<<"id">>, Job),

You can read more about proplists at: http://www.erlang.org/doc/man/proplists.html 您可以在http://www.erlang.org/doc/man/proplists.html上阅读有关支持者的更多信息

Another helper function to access json structure: 另一个访问json结构的辅助函数:

jsonobj({struct,List}) ->
    fun({contains,Key}) ->
        lists:keymember(Key,1,List);
    ({raw,Key}) ->
        {_,Ret} = lists:keyfind(Key,1,List),Ret;
    (Key) ->
        {_,Ret} = lists:keyfind(Key,1,List),
        jsonobj(Ret)
    end;
jsonobj(List) when is_list(List) ->
    fun(len) ->
        length(List);
    (Index) ->
        jsonobj(lists:nth(Index,List))
    end;
jsonobj(Obj) -> Obj.

Usage: 用法:

1> A=mochijson2:decode(<<"{\"job\": {\"id\": \"1\", \"ids\": [4,5,6], \"isok\": true}}">>).
2> B=jsonobj(A).
3> B(<<"job">>).
#Fun<jsonutils.1.33002110>
4> (B(<<"job">>))(<<"id">>).
1
5> (B(<<"job">>))(<<"ids">>).
#Fun<jsonutils.1.9495087>
6> (B(<<"job">>))({raw,<<"ids">>}).
[4,5,6]
7> ((B(<<"job">>))(<<"ids">>))(1).
4
8> B({raw,<<"job">>}).
{struct,[{<<"id">>,<<"1">>},
               {<<"ids">>,[1,2,3]},
               {<<"isok">>,true}]}
9> B({contains,<<"job">>}).
true
10> B({contains,<<"something">>}).
false
11> ((B(<<"job">>))(<<"ids">>))(len)
3

I don't think extracting values from json can be any simpler. 我不认为从json中提取值可以更简单。

Here is another method of accessing the data. 这是另一种访问数据的方法。 Uses records syntax for ease of use. 使用记录语法以方便使用。

-record(struct, {lst=[]}).

A = <<"{\"job\": {\"id\": \"1\"}}">>,
Struct = mochijson2:decode(A), 
Job = proplists:get_value(<<"job">>, Struct#struct.lst),
Id = proplists:get_value(<<"id">>, Job#struct.lst),

Does exactly the same thing as the answer using records instead. 与使用记录的答案完全相同。 Just another option when using mochijson2. 使用mochijson2时的另一个选择。 I personally like this syntax better. 我个人更喜欢这种语法。

添加到前面给出的答案还有一个关于mochiweb,json(视频)的精彩教程

My favourite way of handeling mochijson data is replacing all the struct's with hash maps after which they can be cleanly pattern matched. 我最喜欢使用mochijson数据的方法是用哈希映射替换所有结构,之后它们可以干净地模式匹配。 To do so I wrote this easy to understand function: 为此,我写了这个易于理解的功能:

structs_to_maps({struct, Props}) when is_list(Props) ->
    lists:foldl(
        fun({Key, Val}, Map) ->
            Map#{Key => structs_to_maps(Val)}
        end,
        #{},
        Props
    );
structs_to_maps(Vals) when is_list(Vals) ->
    lists:map(
        fun(Val) ->
            structs_to_maps(Val)
        end,
        Vals
    );
structs_to_maps(Val) ->
    Val.

Here is an example of how to use it: 以下是如何使用它的示例:

do() ->
    A = <<"{\"job\": {\"id\": \"1\"}}">>,
    Data = structs_to_maps(mochijson2:decode(A)),
    #{<<"job">> := #{<<"id">> := Id}} = Data,
    Id.

This has many advantages especially when working with incoming data that can have an unexpected shape. 这具有许多优点,尤其是在处理可能具有意外形状的传入数据时。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM