Decode JSON with mochijson2 in Erlang

后端 未结 5 907
灰色年华
灰色年华 2021-02-10 07:28

I have a var that has some JSON data:

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

Using mochijson2, I decode the data:

相关标签:
5条回答
  • 2021-02-10 07:59

    Adding to the answer given earlier there's also a nice tutorial on mochiweb, json (video).

    0 讨论(0)
  • 2021-02-10 07:59

    My favourite way of handeling mochijson data is replacing all the struct's with hash maps after which they can be cleanly pattern matched. 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.

    0 讨论(0)
  • 2021-02-10 08:02

    The data is in {struct, proplist()} format, so here's what you do:

    {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

    0 讨论(0)
  • 2021-02-10 08:13

    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. I personally like this syntax better.

    0 讨论(0)
  • 2021-02-10 08:15

    Another helper function to access json structure:

    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.

    0 讨论(0)
提交回复
热议问题