2011-06-10 16 views
1

我剛剛開始修改Erlang,並且正在構建一個非常簡單的測試Web應用程序,該應用程序僅用於顯示我的Twitter時間表。如何模式mochijson2返回的匹配結構?

我正在使用webmachine編寫app和erlyDTL來呈現模板。

我的問題與mochiweb的mochijson2:decode/1函數返回的結構有關。

我能成功抓取和deocde我的時間表,如下面的例子:

1> Url = "http://api.twitter.com/1/statuses/user_timeline.json?screen_name=<TWITTER_SCREEN_NAME_HERE>". 
2> inets:start(). 
3> {ok, {_, _, Response}} = httpc:request(Url). 
4> DecodedJson = mochijson2:decode(Response). 

mochijson2:decode/1函數返回格式的元組的列表:

[{struct, proplist()}, {struct, proplist()}, ...] 

然而,通過時間軸into erlyDTL我需要擺脫struct原子標記,並簡單地將一列proplists傳遞給webmachine資源(由erlyDTL呈現)。作爲很新的模式匹配,我盤算了一下,下面的列表理解將實現這一點:

Timeline = [Tweet || {struct, Tweet} <- DecodedJson]. 

事實上,這完全適用於所有在每次發推proplist這樣的項目除了一個,<<"user">>,其值是本身 a {struct, proplist()}元組。我無法想象如何從這個嵌套元組中剔除struct原子,並想知道是否有人可以提供一個Erlang代碼示例,它將模式匹配{struct, Tweet}中的外部Tweet和每個中包含的用戶{struct, User}鳴叫。

的最終目標是要能夠訪問每個鳴叫在Django模板語言如下面的例子:

{{ tweet.text }} <- works 
{{ tweet.created_at }} <- works 
{{ tweet.user.profile_image_url }} <- ??? 

任何幫助將不勝感激!

+0

你能發佈一個實際的例子時間表,顯示你的問題? – DefLog 2011-06-10 18:20:20

回答

0

根據您所描述的結構,你可以嘗試:

timeline(List) -> timeline(List, []). 

timeline([], Result) -> lists:reverse(Result); 
timeline([{struct, S}|T], Result) -> timeline(T, [S|Result]); 
timeline([{<<"user">>, {struct, S}}|T], Result) -> timeline(T, [S|Result]); 
timeline([_|T], Result) -> timeline(T, Result). 

我把這些代碼名爲twitter模塊:

> twitter:timeline([{struct, 1}, {struct, 2}, {<<"user">>, {struct, 3}}, 5]). 
[1,2,3] 

你可能想與這取決於_更換<<"user">>您具體需求。您可能也想介紹某種exception handling,因爲您正在處理來自外部世界的輸入。

+0

感謝大衛 - 因爲我對Erlang非常陌生,所以隨着我的發展,我會將異常處理迭代到應用程序中。現在,我仍然習慣於不去思考Python範例:-) – peeb 2011-06-12 10:28:39

2

下面是我們在內部使用類似用途:

%% @doc Flatten {struct, [term()]} to [term()] recursively. 
destruct({struct, L}) -> 
    destruct(L); 
destruct([H | T]) -> 
    [destruct(H) | destruct(T)]; 
destruct({K, V}) -> 
    {K, destruct(V)}; 
destruct(Term) -> 
    Term. 

對於mochijson2方面的其他用途,KVC可能對你有用:https://github.com/etrepum/kvc

+0

我把它作爲helpers推入模塊:destruct(),它完美地工作。真棒。非常感謝 - 也爲KVC提示。 – peeb 2011-06-12 10:27:05

2

在最近的一個項目香港專業教育學院的工作,我們都處理來自EXT JS前端應用程序的大JSON數據結構。JSON對象的一個​​例子是這裏的下方(這是JSON的只是骨架):

 
{ 
     "presence_token":"734737328233HDHSBSHSYEYEYWYWGWE", 
     "presence_time":"HH:Mins:Secs", 
     "friend_requests": 
     [ 
      { 
       "from":"Username", 
       "type":"buddy", 
       "date":"DD/MM/YY", 
       "time":"HH:Mins:Secs", 
       "name":"Your Full name", 
       "email":"[email protected]" 
      } 
     ], 
     "group_status": 
     [ 
      { 
       "group_name":"ecampus", 
       "status":"running", 
       "members":["phil","josh","shazz"], 
       "start_date":"DD/MM/YY", 
       "start_time":"HH:Mins:Secs"    
      }, 
      { 
       "group_name":"buganda", 
       "status":"off" 
      } 
     ], 
     "friend_status": 
     [ 
      { 
       "friend":"Friend_username", 
       "status":"online", 
       "log_on_time":"HH:Mins:Secs", 
       "state":"available", 
       "name":"Friend_Fullname", 
       "email":"[email protected]"    
      }, 
      { 
       "friend":"Friend_username", 
       "status":"offline",     
       "name":"Friend_Fullname", 
       "email":"[email protected]"    
      }   
     ]   
    } 

mochijson2:decode/1,該結構物我有看起來像這樣:

 
     {struct,[{<<"presence_token">>, 
        <<"734737328233HDHSBSHSYEYEYWYWGWE">>}, 
       {<<"presence_time">>,<<"HH:Mins:Secs">>}, 
       {<<"friend_requests">>, 
        [{struct,[{<<"from">>,<<"Username">>}, 
          {<<"type">>,<<"buddy">>}, 
          {<<"date">>,<<"DD/MM/YY">>}, 
          {<<"time">>,<<"HH:Mins:Secs">>}, 
          {<<"name">>,<<"Your Full name">>}, 
          {<<"email">>,<<"[email protected]">>}]}]}, 
       {<<"group_status">>, 
        [{struct,[{<<"group_name">>,<<"ecampus">>}, 
          {<<"status">>,<<"running">>}, 
          {<<"members">>,[<<"phil">>,<<"josh">>,<<"shazz">>]}, 
          {<<"start_date">>,<<"DD/MM/YY">>}, 
          {<<"start_time">>,<<"HH:Mins:Secs">>}]}, 
        {struct,[{<<"group_name">>,<<"buganda">>}, 
          {<<"status">>,<<"off">>}]}]}, 
       {<<"friend_status">>, 
        [{struct,[{<<"friend">>,<<"Friend_username">>}, 
          {<<"status">>,<<"online">>}, 
          {<<"log_on_time">>,<<"HH:Mins:Secs">>}, 
          {<<"state">>,<<"available">>}, 
          {<<"name">>,<<"Friend_Fullname">>}, 
          {<<"email">>,<<"[email protected]">>}]}, 
        {struct,[{<<"friend">>,<<"Friend_username">>}, 
          {<<"status">>,<<"offline">>}, 
          {<<"name">>,<<"Friend_Fullname">>}, 
          {<<"email">>,<<"[email protected]">>}]}]}]} 

現在我決定創建一個模塊將這個結構轉換爲一個「深」的proplist,這個模塊將包含一個函數struct:all_keys/1,如果我給它提供結構對象,它會以有組織的方式生成列表和元組。下面是代碼:

 
-module(struct). 
-export([all_keys/1]). 

is_struct({struct,_}) -> true; 
is_struct(_) -> false. 

to_binary(S) when is_list(S)-> list_to_binary(S); 
to_binary(S) when is_integer(S)-> S; 
to_binary(S) when is_atom(S)-> to_binary(atom_to_list(S)); 
to_binary(S) -> S. 

to_value(V) when is_binary(V)-> binary_to_list(V); 
to_value(V) when is_integer(V)-> V; 
to_value(V) when is_list(V)-> 
    try list_to_integer(V) of 
     PP -> PP 
    catch 
     _:_ -> 
      try list_to_float(V) of 
       PP2 -> PP2 
      catch 
       _:_ -> V 
      end 
    end; 
to_value(A)-> A. 

to_value2({struct,L})-> 
    all_keys({struct,L}); 
to_value2([{struct,_L}|_Rest] = LL)-> 
    [all_keys(XX) || XX <- LL]; 
to_value2(D) when is_binary(D)-> to_value(D); 
to_value2(D) when is_list(D)-> 
    [to_value2(Any) || Any <- D].  

all_keys({struct,L})-> 
    [{to_value(Key),to_value2(Val)} || {Key,Val} <- L]; 
all_keys(List)-> [all_keys(X) || X <- List]. 

現在,調用struct:all_keys(Struct_object)會給這個輸出:

 
[{"presence_token",P_token}, 
{"presence_time",P_time}, 
{"friend_requests", 
    [[{"from","Username"}, 
    {"type","buddy"}, 
    {"date","DD/MM/YY"}, 
    {"time","HH:Mins:Secs"}, 
    {"name","Your Full name"}, 
    {"email","[email protected]"}]]}, 
{"group_status", 
    [[{"group_name","ecampus"}, 
    {"status","running"}, 
    {"members",["phil","josh","shazz"]}, 
    {"start_date","DD/MM/YY"}, 
    {"start_time","HH:Mins:Secs"}], 
    [{"group_name","buganda"},{"status","off"}]]}, 
{"friend_status", 
    [[{"friend","Friend_username"}, 
    {"status","online"}, 
    {"log_on_time","HH:Mins:Secs"}, 
    {"state","available"}, 
    {"name","Friend_Fullname"}, 
    {"email","[email protected]"}], 
    [{"friend","Friend_username"}, 
    {"status","offline"}, 
    {"name","Friend_Fullname"}, 
    {"email","[email protected]"}]]}] 

以上proplist這樣更容易與工作比結構對象。但是,您可能會發現另一個版本的結構模塊,特別是在着名的mochiweb示例中,這個示例名爲粘滯便箋,其鏈接我現在沒有。上面粘貼的結構模塊應該能夠幫助您使用mochijson2。 成功

+1

我試圖使用你的代碼,並發現一個錯誤。在「{」from「,」Username「}之前有兩個」[[「),但代碼對於進一步修改非常有幫助。 – 2012-03-19 13:13:29