当前位置: 首页 > 工具软件 > Racket > 使用案例 >

Racket读写JSON

东方宜
2023-12-01

JSON

Eli Barzilay
and Dave Herman

 

 (require json) package: base

 

这个库提供了一些实用程序,用于解析和生成JSON数据交换格式到(来自)Racket值的数据。有关JSON的更多信息,请参阅 JSON web siteJSON RFC

JS-表达式(JS-Expressions)

 

procedure

(jsexpr? x [#:null jsnull]) → boolean?

  x : any/c
  jsnull : any/c = (json-null)

执行深入检查以确定x是否为jsexpr。

 

这个库定义了Racket值的一个子集,这些值可以表示为JSON字符串,这个判断检查这些值。JS表达式或jsexpr是:

  • jsnull的值,默认情况下为'null。

  • boolean?

  • string?

  • (or/c exact-integer? inexact-real?)

  • (listof jsexpr?)

  • (and/c hash-eq? (hash/c symbol? jsexpr?))

 

Examples:

> (jsexpr? 'null)

#t

> (jsexpr? #t)

#t

> (jsexpr? "cheesecake")

#t

> (jsexpr? 3.5)

#t

> (jsexpr? (list 18 'null #f))

#t

> (jsexpr? #hasheq((turnip . 82)))

#t

> (jsexpr? (vector 1 2 3 4))

#f

> (jsexpr? #hasheq(("turnip" . 82)))

#f

 

 

parameter

(json-null) → any/c

(json-null jsnull) → void?
  jsnull : any/c

此参数确定与JSON“null”对应的默认Racket值。默认情况下,它是'null符号。在某些情况下,不同的值可能更适合您的需要,因此此库中的所有函数都接受用于表示JSON“null”的值的#:null关键字参数,而此参数默认为(json-null)。

 

从JS表达式生成JSON文本

 

procedure

(write-json x    
  [out    
  #:null jsnull    
  #:encode encode])  any
  x : jsexpr?
  out : output-port? = (current-output-port)
  jsnull : any/c = (json-null)
  encode : (or/c 'control 'all) = 'control

将编码为JSON的x jsexpr写入输出端口。

 

默认情况下,只有ASCII控制字符编码为“\uHHHH”。如果encode被指定为'all,那么除了ASCII控制字符之外,非ASCII字符也被编码。如果您需要通过可能不支持UTF-8的通道传输文本,这将非常有用。请注意,U+10000及以上范围内的字符编码为两个\uHHHH转义符,请参阅 JSON RFC 第2.5节。

 

Examples:

> (with-output-to-string
    (λ () (write-json #hasheq((waffle . (1 2 3))))))

"{\"waffle\":[1,2,3]}"

> (with-output-to-string
    (λ () (write-json #hasheq((와플 . (1 2 3)))
                      #:encode 'all)))

"{\"\\uc640\\ud50c\":[1,2,3]}"

 

 

procedure

(jsexpr->string x    
  [#:null jsnull    
  #:encode encode])  string?
  x : jsexpr?
  jsnull : any/c = (json-null)
  encode : (or/c 'control 'all) = 'control

为jsexpr x生成JSON源字符串。

 

 

Example:

> (jsexpr->string #hasheq((waffle . (1 2 3))))

"{\"waffle\":[1,2,3]}"

 

 

procedure

(jsexpr->bytes x    
  [#:null jsnull    
  #:encode encode])  bytes?
  x : jsexpr?
  jsnull : any/c = (json-null)
  encode : (or/c 'control 'all) = 'control

为jsexpr x生成一个JSON源字节字符串(字节字符串用UTF-8编码)

 

 

Example:

> (jsexpr->bytes #hasheq((waffle . (1 2 3))))

#"{\"waffle\":[1,2,3]}"

 

将JSON文本解析为JS表达式

 

procedure

(read-json [in #:null jsnull]) → (or/c jsexpr? eof-object?)

  in : input-port? = (current-input-port)
  jsnull : any/c = (json-null)

以Racket(不可变)值的形式从中的JSON编码输入端口读取jsexpr,如果只剩下空白,则生成eof。

 

 

Examples:

> (with-input-from-string
    "{\"arr\" : [1, 2, 3, 4]}"
    (λ () (read-json)))

'#hasheq((arr . (1 2 3 4)))

> (with-input-from-string
    "sandwich sandwich" ; invalid JSON
    (λ () (read-json)))

read-json: bad input

 

 

procedure

(string->jsexpr str [#:null jsnull]) → jsexpr?

  str : string?
  jsnull : any/c = (json-null)

将JSON字符串str解析为不可变的jsexpr。

 

 

Example:

> (string->jsexpr "{\"pancake\" : 5, \"waffle\" : 7}")

'#hasheq((waffle . 7) (pancake . 5))

 

 

procedure

(bytes->jsexpr str [#:null jsnull]) → jsexpr?

  str : bytes?
  jsnull : any/c = (json-null)

将JSON字节字符串str解析为不可变的jsexpr。

 

 

Example:

> (bytes->jsexpr #"{\"pancake\" : 5, \"waffle\" : 7}")

'#hasheq((waffle . 7) (pancake . 5))

 

关于设计的一些话

4.1 JS表达式数据类型

JSON在语法上区分了“null”、数组文本和对象文本,因此有一个问题是什么Racket值应该表示JSON“null”。默认情况下,此库使用Racket 'null符号。注意,这是明确的,因为Racket符号仅用作对象键,在JSON中,对象键必须是字符串。

其他几种选择已被各种库使用。例如,Dave Herman的PLaneT库(它是这个库的基础)使用了#\nul字符,Racket和其他Lisp的其他库采用(void),NIL(有些库还用于JSON“false”)等等。这个库采用的方法是对所有函数使用关键字参数,参数决定其默认值,这样就可以方便地使用任何符合您需要的值。

JSON JSON RFC 只声明对象文本表达式“应该”包含唯一键,但并不完全禁止它们。从现有的实践来看,流行的JSON库通过简单地选择一个键值对并丢弃其他具有相同键的键值对来解析具有重复键的对象文本。这种行为自然地与Racket哈希表并行,使它们成为自然的模拟。

最后, JSON RFC 几乎完全没有提到键值对的顺序。虽然RFC只指定JSON的语法,当然JSON必须始终将对象文本表示为有序的集合,但简介中指出:

对象是零个或多个名称/值对的无序集合,其中名称是字符串,值是字符串、数字、布尔值、空值、对象或数组。

实际上,JSON库放弃了解析JSON文本中对象文本的顺序,并且不保证生成的对象文本的顺序,通常使用某种风格的哈希表作为自然选择。因此,我们也这样做。

4.2 命名约定

这个库中有些名称使用“jsexpr”,有些使用“json”。第一种用于我们的陈述,第二种用于从外部世界接收或发送给外部世界的信息。

 类似资料: