2010-04-29 37 views
5

Tôi có một var rằng có một số dữ liệu JSON:Giải mã JSON với mochijson2 trong Erlang

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

Sử dụng mochijson2, tôi giải mã dữ liệu:

Struct = mochijson2:decode(A). 

Và bây giờ tôi có điều này:

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

Tôi đang cố gắng đọc (ví dụ), "công việc" hoặc "id".

Tôi đã thử sử dụng struct.get_value nhưng có vẻ như nó không hoạt động.

Bất kỳ ý tưởng nào?

Trả lời

13

Dữ liệu được trong {struct, proplist) (} định dạng, vì vậy đây là những gì bạn làm:

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

Bạn có thể đọc thêm về proplists tại địa chỉ: http://www.erlang.org/doc/man/proplists.html

1

Thêm vào câu trả lời cho trước có cũng là một số tutorial đẹp trên mochiweb, json (video).

2

Đây là một phương pháp khác để truy cập dữ liệu. Sử dụng records syntax để dễ sử dụng.

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

Thực hiện tương tự như câu trả lời bằng cách sử dụng hồ sơ thay thế. Chỉ cần một tùy chọn khác khi sử dụng mochijson2. Cá nhân tôi thích cú pháp này tốt hơn.

5

Một chức năng helper để truy cập cấu trúc 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. 

Cách sử dụng:

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 

Tôi không nghĩ giải nén các giá trị từ json thể được bất kỳ đơn giản hơn.

1

Cách yêu thích của tôi về việc xử lý dữ liệu mochijson đang thay thế tất cả các cấu trúc bằng các bản đồ băm sau đó chúng có thể được tạo mẫu phù hợp. Để làm như vậy, tôi đã viết dễ hiểu chức năng này:

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. 

Dưới đây là một ví dụ về cách sử dụng nó:

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

này có nhiều ưu điểm đặc biệt là khi làm việc với dữ liệu đến rằng có thể có một bất ngờ hình dạng.

Các vấn đề liên quan