json - 在 lisp 中写 json 对象

标签 json lisp common-lisp

早上好,我需要帮助来用 lisp 编写这个函数。 这是描述。

The json-write function writes the JSON object to the filename file in JSON syntax. If filename does not exist, it is created and if it exists it is overwritten. Of course it is expected that

    CL-PROMPT> (json-load (json-write '(json-obj # | stuff | #) "foo.json"))
    (json-obj # | stuff | #)

这是我的功能,但不正确

 (defun json-write (json filename)
  (with-open-file (out filename
                       :direction :output
                       :if-exists :overwrite
                       :if-does-not-exist :create)
    (pprint (json out))))

谢谢

编辑 1:

我尝试将 var json(这是一个 json 对象)写入文件名。

但是 pprint 没有向文件名写入任何内容

编辑 2:

(defun json-write (json filename)
  (with-open-file (out filename
                       :direction :output
                       :if-exists :supersede
                       :if-does-not-exist :create)
    (cond
     ((equal (first json) ‘json-array) (write-arr json))
     ((equal (first json) ‘json-obj) (write-obj json)))))

所以我现在试试这个

如果 json 是 json-array lisp 调用 write-arr json 如果 json 是 json-obj 调用 write-obj

所以我的想法是write-arr transform

(json-array 1 2 3) in `"[1, 2, 3]"` to make it parsable 

和写入对象转换

(json-obj ("nome" "Arthur") ("cognome" "Dent"))

"{\"nome\" : \"Arthur\",
\"cognome\" : \"Dent\"}"

然后将所有内容以流格式写入文件名。

我如何在“[1, 2, 3]”中格式化 (json-array 1 2 3)。

有格式化功能?然后递归调用这个函数?

谢谢

最佳答案

当您编写 (pprint (json out)) 时,您正在尝试调用名为 json 的全局函数。我想你的意思是 (pprint json out)

下面大致介绍一下如何编写一个简单的json打印机:

(defun write-json (object stream)
  (etypecase object
    (number (format stream “~a” object))
    (string (print object stream))
    (null (format stream “null”))
    (cons
      (ecase (car object)
        (json-array
          (write-char #\[ stream)
          (loop for (x . r) on (cdr object)
            do (write-json x stream)
               (when r (write-char #\, stream)))
          (write-char #\] stream))))))

有很多空白需要填补。请注意,如果字符串包含新行,这将打印错误的字符串。你可能想做一些不那么愚蠢的事情来打印数字。

下面是我如何使用 CLOS 实现一个 json pretty-print :

(defvar *json-pretty* nil)
(defvar *json-indent-level* 0)
(defvar *json-indent-spaces* 2)
(defun json-fresh-line (stream)
  (if *json-pretty*
    (progn
      (fresh-line stream)
      (loop repeat (* *json-indent-level* *json-indent-spaces*)
        do (write-char #\Space stream)))
    (write-char #\Space stream))
(defgeneric write-json (object stream))
(defgeneric write-json-collection (type data stream))
(defmethod write-json ((object cons) stream)
  (write-json-collection (car object) (cdr object) stream))
(defmethod write-json-collection ((tag (eql json-array)) data stream)
  ...)

还有很多方法要写。

关于json - 在 lisp 中写 json 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48258189/

相关文章:

MySQL在数组中按键搜索json值

c - 是否有可能将类似 Lisp 的宏构建成命令式语言?

lisp - 如何仅使用 cons 将值附加到现有列表?

macros - 为什么这个 Lisp 宏作为一个整体可以工作,即使每个部分都不起作用?

lisp - 在 Lisp 函数中定义一个语法错误

directory - 如何翻译 (make-pathname :directory '(:absolute :home "directoryiwant") into absolute path

Android 从存储在 JSONObject 中的 URL 获取图像

c# - HttpClient PostAsJsonAsync 方法无法正常工作(序列化无法正常工作)

asp.net - 过滤掉 ASP.NET Core API 中的属性

emacs - 为什么 elisp 局部变量在这种情况下保持其值?