如何使用Yojson迭代JSON对象中的键/成员?

时间:2016-02-20 05:24:11

标签: json key ocaml

到目前为止我能看到的关于处理json对象的唯一例子涉及事先知道密钥,但是我如何能够通过密钥/成员并单独处理它们的值?

2 个答案:

答案 0 :(得分:2)

假设您已经创建了json实例,可能是通过使用Yojson.Basic.from_channel (open_in filename)读取文件或使用Yojson.Basic.from_string string从字符串读取,您可以使用{将其转换为关联列表{1}}并递归迭代它,如下所示:

Yojson.Basic.Util.to_assoc

open Yojson.Basic let iter js = let rec f (nm,j) = Printf.printf "\"%s\": " nm; match j with | `Assoc a -> Printf.printf "assoc\n"; List.iter f a | `Bool b -> Printf.printf "bool: %b\n" b | `Float f -> Printf.printf "float: %f\n" f | `Int i -> Printf.printf "int: %d\n" i | `List jl -> Printf.printf "list: ["; List.iter (List.iter f) (List.map Util.to_assoc jl); Printf.printf "]\n" | `Null -> Printf.printf "null\n" | `String s -> Printf.printf "string: \"%s\"\n" s in List.iter f (Util.to_assoc js) 函数首先将其iter参数转换为关联列表,然后使用函数js对其进行迭代。 f函数采用字符串和f类型的元组参数。为了这个例子,它打印字符串,然后匹配json类型并相应地对其进行操作。请注意json如何递归处理f`Assoc变体的值。

答案 1 :(得分:2)

Yojson旨在充当atdgen的运行时。 Atdgen通过将JSON数据转换为OCaml类型的数据来为用户节省大量时间,反之亦然。

solution for JSON objects representing association lists如下(示例源文件assoc.atd):

type t = (string * foo) list <json repr="object">

type foo = {
  x: int;
  y: int;
}

JSON格式的t类型的示例数据:

{
  "p1": { "x": 1, "y": 2 },
  "p2": { "x": 14, "y": 0 },
  "q": { "x": 9, "y": -1 }
}

此示例生成的界面为:

(* This is file assoc_j.mli derived from assoc.atd.
   It provides the serializers and deserializers for JSON.
   Other files are generated for other purposes,
   including assoc_t.mli which contains only the OCaml
   type definitions.
 *)

type foo = Assoc_t.foo = { x: int; y: int }

type t = Assoc_t.t

val write_foo :
  Bi_outbuf.t -> foo -> unit
  (** Output a JSON value of type {!foo}. *)

val string_of_foo :
  ?len:int -> foo -> string
  (** Serialize a value of type {!foo}
      into a JSON string.
      @param len specifies the initial length
                 of the buffer used internally.
                 Default: 1024. *)

val read_foo :
  Yojson.Safe.lexer_state -> Lexing.lexbuf -> foo
  (** Input JSON data of type {!foo}. *)

val foo_of_string :
  string -> foo
  (** Deserialize JSON data of type {!foo}. *)

val write_t :
  Bi_outbuf.t -> t -> unit
  (** Output a JSON value of type {!t}. *)

val string_of_t :
  ?len:int -> t -> string
  (** Serialize a value of type {!t}
      into a JSON string.
      @param len specifies the initial length
                 of the buffer used internally.
                 Default: 1024. *)

val read_t :
  Yojson.Safe.lexer_state -> Lexing.lexbuf -> t
  (** Input JSON data of type {!t}. *)

val t_of_string :
  string -> t
  (** Deserialize JSON data of type {!t}. *)