2012-01-08 23 views
2

我想使用webclient模塊來查詢couchDB休息接口(我使用它而不是opa couchdb API,因爲我需要獲得特定數量的文檔)。解析一個webclient.Result內容在OPA

這裏是用來做查詢代碼:

listmydocs(dburi)= 
match WebClient.Get.try_get(dburi) with 
     | { failure = _ } -> print("error\n") 
     | {success=s} -> match WebClient.Result.get_class(s) with 
      | {success} -> print("{s.content}")        
      | _   -> print("Error {s.code}") 
     end 

在s.content給出的結果是以下字符串:

{"total_rows":177,"offset":0,"rows":[ 
{"id":"87dc6b6d9898eff09b1c8602fb00099b","key":"87dc6b6d9898eff09b1c8602fb00099b","value":{"rev":"1-853bd502e3d80d08340f72386a37f13a"}}, 
{"id":"87dc6b6d9898eff09b1c8602fb000f17","key":"87dc6b6d9898eff09b1c8602fb000f17","value":{"rev":"1-4cb464c6e1b773b9004ad28505a17543"}} 
]} 

我想知道什麼將是最好的方法解析這個字符串得到例如id列表,或者只有行字段? 我試圖使用Json.deserialize(s.content),但不知道從那裏去哪裏。

回答

3

你可以有幾個辦法,OPA 2個反序列化的Json字符串:

1 - 第一個是簡單地使用Json.deserialize接受一個字符串,按照到JSON規範產生一個JSON AST。 然後你可以匹配產生的AST來檢索你想要的信息。

match Json.deserialise(a_string) with 
| {none} -> /*Error the string doesn't respect json specification*/ 
| {some = {Record = record}} -> 
/* Then if you want 'total_rows' field */ 
    match List.assoc("total_rows", record) with 
    | {some = {Int = rows}} -> rows 
    | {none} -> /*Unexpected json value*/ 

2 - 另一種方法是使用Json的「magic」opa deserilization。首先定義對應於期望值的Opa類型。然後使用OpaSerialize。*函數。根據你的例子

type result = { 
    total_rows : int; 
    offset : int; 
    rows : list({id:string; key:string; value:{rev:string}}) 
} 
match Json.deserialize(a_string) 
| {none} -> /*Error the string doesn't respect json specification*/ 
| {some = jsast} -> 
    match OpaSerialize.Json.unserialize_unsorted(jsast) with 
    | {none} -> /*The type 'result' doesn't match jsast*/ 
    | {some = (value:result) /*The coercion is important, it give the type information to serialize mechanism*/} -> 
    /* Use value as a result record*/ 
    value.total_rows 
+1

謝謝,「魔術」opa反序列化方法絕對是我正在尋找的。 – jeant 2012-01-09 09:55:19