【问题标题】:Decode JSON with mochijson2 in Erlang在 Erlang 中使用 mochijson2 解码 JSON
【发布时间】:2011-02-13 22:14:26
【问题描述】:

我有一个包含一些 JSON 数据的 var:

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

使用 mochijson2 解码数据:

 Struct = mochijson2:decode(A). 

现在我有了这个:

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

我正在尝试阅读(例如)“job”或“id”。

我尝试使用 struct.get_value 但它似乎不起作用。

有什么想法吗?

【问题讨论】:

    标签: json erlang mochiweb mochijson2


    【解决方案1】:

    数据是 {struct, proplist()} 格式,所以你可以这样做:

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

    您可以阅读更多关于 proplists 的信息:http://www.erlang.org/doc/man/proplists.html

    【讨论】:

      【解决方案2】:

      另一个访问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.
      

      用法:

      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
      

      我认为从 json 中提取值再简单不过了。

      【讨论】:

        【解决方案3】:

        这是访问数据的另一种方法。使用records syntax 方便使用。

        -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),
        

        与使用记录的答案完全相同。使用 mochijson2 时的另一种选择。我个人更喜欢这种语法。

        【讨论】:

          【解决方案4】:

          除了前面给出的答案之外,mochiweb 上还有一个不错的 tutorial,json(视频)。

          【讨论】:

            【解决方案5】:

            我最喜欢的处理 mochijson 数据的方法是用哈希映射替换所有结构,之后它们可以进行干净的模式匹配。为此,我编写了这个易于理解的函数:

            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.
            

            以下是如何使用它的示例:

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

            这有很多优点,尤其是在处理可能具有意外形状的传入数据时。

            【讨论】:

              猜你喜欢
              • 2010-11-07
              • 1970-01-01
              • 2010-12-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-02-25
              • 1970-01-01
              • 2012-12-07
              相关资源
              最近更新 更多