2010-04-29 60 views
5

mochijson2我有了一些JSON数据的VAR:解码JSON在二郎

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

使用mochijson2,我对数据进行解码:

Struct = mochijson2:decode(A). 

现在我有这样的:

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

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

我试过使用struct.get_value,但它似乎不工作。

任何想法?

回答

13

的数据是{结构,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

1

添加到给出的答案前面有在mochiweb上,json(视频)也是一个不错的tutorial

2

这是另一种访问数据的方法。为便于使用,使用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时只是另一种选择。我个人更喜欢这个语法。

5

另一个辅助函数来访问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中提取值可以是任何简单。

1

我最喜欢handeling 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. 

这与可以有意想不到的传入数据时,特别是有很多好处形状。