how create new type in package Yojson Ocaml

I have json file test.json

{"response":[
    {
        "aid":209228783,
        "thumb_id":"348954492",
        "owner_id":-79421906,
        "title":"title1",
        "description":"description1",
        "created":"1420821911",
        "updated":"1421783832",
        "size":284,
        "can_upload":1
    },
    {
        "aid":205134660,
        "thumb_id":"353880937",
        "owner_id":-79421906,
        "title":"title2",
        "description":"description2",
        "created":"1415386976",
        "updated":"1425057394",
        "size":308,
        "can_upload":0
    },
    {
        "aid":204502901,
        "thumb_id":"347548800",
        "owner_id":-79421906,
        "title":"title3",
        "description":"description3",
        "created":"1414438611",
        "updated":"1419706388",
        "size":1030,
        "can_upload":0
    }
]}

Example, need get from json file values "aid", "description" and "size". I create new type response

    type response = {
      aid: int;
      thumb_id: string;
      owner_id: int;
      title: string;
      description: string;
      created: string;
      updated: string;
      size: int;
      can_upload: int
    }

How i can use this is type in my json request

    let des json =
       [json]
        |> filter_member "response"
        |> flatten
        |> to_list;;
    let json = Yojson.Basic.from_file "test.json" in
    List.iter (fun y -> print_endline(y.aid^"--->"^y.title)) (des json);;

This code is return error wrong type.

Upvotes: 1

Views: 346

Answers (2)

Martin Jambon
Martin Jambon

Reputation: 4939

Yojson is really just the runtime for atdgen. Put the type definitions into a .atd file and atdgen will produce the boilerplate code for you using yojson:

(* This is file api.atd *)

type response_item = {
  aid: int;
  thumb_id: string;
  owner_id: int;
  title: string;
  description: string;
  created: string;
  updated: string;
  size: int;
  can_upload: int
}

type response = {
  response: response_item list;
}

Atdgen produces files api_t.mli, api_t.ml, api_j.mli, and api_j.ml, where _t stands for types and _j stands for JSON. See the tutorial on how to integrate atdgen with your build system.

Then from your OCaml code, all you have to do is:

let record_list =
  Ag_util.Json.from_file Api_j.read_response "test.json"

Upvotes: 0

user1971598
user1971598

Reputation:

(Making your response record just a bit smaller but still getting the point across)

type response = {descr:string;
                 size: int;
                 can_upload: int}

let record_list =
  let open Yojson.Basic.Util in 
  let f = Yojson.Basic.from_file "test.json" in
  List.fold_right
    (fun item r_list ->
     {descr = member "description" item |> to_string;
      size = member "size" item |> to_int;
      can_upload = member "can_upload" item |> to_int} :: r_list)
    (member "response" f |> to_list)
    [] 

Upvotes: 3

Related Questions