请问,Autolisp/Visuallisp有读写Json格式的API吗?
请问,Autolisp/Visuallisp有读写Json格式的API吗?alisp的中间数据文件,存成什么格式合适?直接append->write-line为lisp表,还是什么?
如能存json当然最好,直观查看,也与其他语言工具通用
本帖最后由 e2002 于 2022-4-21 10:26 编辑
如果需要和其他语言共同使用这些中间数据,用json格式确实比较合适,但 AutoLISP没有现成的读写json的函数,只能自己写一个专门的函数库,当然,如果你能在github上搞个这样的开源项目就更好了,大家一起打造这个库。 e2002 发表于 2022-4-21 10:20
如果需要和其他语言共同使用这些中间数据,用json格式确实比较合适,但 AutoLISP没有现成的读写json的函数 ...
感谢版主提供信息。
Lisp的Json读写API,,感觉这基础功能很重要,通用数据交流的桥梁。
如果写个小Arx会方便很多。给lisp用,属性数据的CRUD都归lisp的表,Arx纯转换<表--Json>不涉及acad对象,那么版本兼容性也会不错,不挑cad版本.
本帖最后由 e2002 于 2022-4-21 12:11 编辑
如果数据的创建和处理都在 AutoCAD内部,直接使用list即可,毕竟 LISP处理 list 数据太方便了。
只是数据的对外保存用一个 list2json函数,读取再写一个 json2list。
本帖最后由 landsat99 于 2022-4-21 12:35 编辑
e2002 发表于 2022-4-21 12:10
如果数据的创建和处理都在 AutoCAD内部,直接使用list即可,毕竟 LISP处理 list 数据太方便了。
嗯呢。赞同您的意见!
我对lisp不熟,刚接触。感觉Lisp作为dwg图形数据的api可能很合适,,作通用处理 计算 分析可能比较勉强。
不太确定这种以正则为主的操作,适不适合lisp写;不合适的话就作个arx小函数。 Github有个俄罗斯小哥发布过Autolisp-Json的 读取函数。供大家参考
代码如下
; AutoLISP JSON parser and formatter
; (c) 2015, Michel Beloshitsky <mbeloshitsky@gmail.com>
;
; TODO:
; - Correct numbers handling
; - Write formatter
; - Remove parasite (list) == nil equivalence
(setq json:debug F)
(defun debug-print (text)
(if (= T json:debug)
(princ text)))
(defun string2list (string)
(setq output (list))
(foreach charcode (vl-string->list string)
(setq output (cons (chr charcode) output)))
(reverse output))
(defun starts-with (pfx stringlist)
(setq pfxlist (string2list pfx))
(setq result T)
(while (not (= pfxlist (list)))
(setq x (car pfxlist))
(setq y (car stringlist))
(setq pfxlist (cdr pfxlist))
(setq stringlist (cdr stringlist))
(if (not (= x y))
(setq result F)))
(setq result result))
(defun drop (n lst)
(while (< 0 n)
(setq lst (cdr lst))
(setq n (- n 1)))
(setq lst lst))
(defun take (n lst)
(setq output (list))
(while (< 0 n)
(setq output (cons (car lst) output))
(setq lst (cdr lst))
(setq n (- n 1)))
(reverse output))
(defun readhex (hexlist)
(defun hex2num (hex) (cond
((= hex "0") 0)((= hex "1") 1)((= hex "2") 2)((= hex "3") 3)((= hex "4") 4)((= hex "5") 5)((= hex "6") 6)
((= hex "7") 7) ((= hex "8") 8)((= hex "9") 9)
((= hex "a") 10) ((= hex "b") 11) ((= hex "c") 12) ((= hex "d") 13)((= hex "e") 14) ((= hex "f") 15)
((= hex "A") 10) ((= hex "B") 11) ((= hex "C") 12) ((= hex "D") 13) ((= hex "E") 14) ((= hex "F") 15)
))
(setq output 0)
(while (not (= hexlist (list)))
(setq output (+ (* output 16) (hex2num (car hexlist))))
(setq hexlist (cdr hexlist))
)
(setq output output))
(defun json:read (jsonText)
; Так как а автолиспе ниче нет, то разбор производим стейт-машиной c магазином
(setq curr-atom "")
(setq curr-key "")
(setq curr-dict (list))
(setq dict-history (list))
(defun isdigit (ch)
(or (= ch "0") (= ch "1") (= ch "2") (= ch "3") (= ch "4") (= ch "5") (= ch "6") (= ch "7") (= ch "8") (= ch "9")))
(defun isspace (ch)
(or (= ch " ") (= ch "\t") (= ch "\n") (= ch "\r")))
(defun push-kv ()
(if (not (= curr-key ""))
(setq curr-dict (cons (cons curr-key curr-atom) curr-dict)))
(setq curr-key "")
(setq curr-atom ""))
(setq curr-array (list))
(setq array-history (list))
(setq string-delim "")
(setq state "object")
(setq state-history (list))
(setq error-message "")
(defun report-error (message)
(push-state "error")
(setq error-message message)
(setq jsonList (list)))
(defun pop-state ()
(debug-print (strcat "\n-" state))
(setq state (car state-history))
(setq state-history (cdr state-history)))
(defun push-state (new-state)
(debug-print (strcat "\n+" new-state))
(setq state-history (cons state state-history))
(setq state new-state))
(defun skip ()
(setq a ""))
(setq escaping F)
(setq jsonList (string2list jsonText))
(while (not (= jsonList (list)))
(setq ch (car jsonList))
(setq jsonList (cdr jsonList))
(cond
((= state "up") (progn
(setq jsonList (cons ch jsonList))
(pop-state)
(pop-state)))
((= state "object") (cond
((isspace ch) (skip))
((= ch "{") (progn
(setq dict-history (cons (list curr-key curr-dict) dict-history))
(setq curr-key "")
(setq curr-dict (list))
(push-state "object-next")
))
(T (report-error (strcat "Unexpected " ch " instead of { or space")))
))
((= state "object-semi") (cond
((isspace ch) (skip))
((= ch ":") (progn
(setq curr-key curr-atom)
(pop-state)
(push-state "object-next")
(push-state "value")))
(T (report-error (strcat "Unexpected " ch " instead of : or space")))
))
((= state "object-next") (cond
((isspace ch) (skip))
((= ch "\"") (progn
(setq jsonList (cons ch jsonList))
(pop-state)
(push-state "object-semi")
(push-state "string")))
((= ch ",") (progn
(push-kv)
(pop-state)
(push-state "object-semi")
(push-state "string")))
((= ch "}") (progn
(push-kv)
(setq curr-atom curr-dict)
(setq dh (car dict-history))
(setq dict-history (cdr dict-history))
(setq curr-key (nth 0 dh))
(setq curr-dict (nth 1 dh))
(pop-state)
(pop-state)))
(T (report-error (strcat "Unexpected " ch " instead of , or } or space")))
))
((= state "array") (cond
((isspace ch) (skip))
((= ch "[") (progn
(setq array-history (cons curr-array array-history))
(setq curr-array (list))
(push-state "array-next")
))
(T (report-error (strcat "Unexpected " ch " instead of [ or space")))
))
((= state "array-next") (cond
((isspace ch) (skip))
((= ch ",") (progn
(setq curr-array (cons curr-atom curr-array))
(pop-state)
(push-state "array-next")
(push-state "value")))
((= ch "]") (progn
(setq curr-array (cons curr-atom curr-array))
(setq curr-atom (reverse curr-array))
(setq curr-array (car array-history))
(setq array-history (cdr array-history))
(pop-state)
(pop-state)
))
(T (progn
(setq jsonList (cons ch jsonList))
(push-state "value")))
))
((= state "value") (cond
((isspace ch) (skip))
((= ch "\"")
(progn
(setq jsonList (cons ch jsonList))
(push-state "up")
(push-state "string")))
((= ch "'")
(progn
(setq jsonList (cons ch jsonList))
(push-state "up")
(push-state "string")))
((= ch "{")
(progn
(setq jsonList (cons ch jsonList))
(push-state "up")
(push-state "object")))
((= ch "[") (progn
(setq jsonList (cons ch jsonList))
(push-state "up")
(push-state "array")))
((or (= ch "-") (isdigit ch))
(progn
(setq jsonList (cons ch jsonList))
(setq curr-atom "")
(push-state "up")
(push-state "number")))
((starts-with "true" (cons ch jsonList))
(progn
(setq jsonList (drop 3 jsonList))
(setq curr-atom 'true)
(pop-state)))
((starts-with "false" (cons ch jsonList))
(progn
(setq jsonList (drop 4 jsonList))
(setq curr-atom 'false)
(pop-state)))
((starts-with "null" (cons ch jsonList))
(progn
(setq curr-atom 'null)
(setq jsonList (drop 3 jsonList))
(pop-state)))
(T (report-error (strcat "Unexpected " ch " instead of JSON value")))
))
((= state "string") (cond
((isspace ch) (skip))
((or (= ch "'") (= ch "\""))
(progn
(setq curr-atom "")
(setq string-delim ch)
(push-state "instring")
))
(T (report-error (strcat "Unexpected " ch " instead of \" or space")))
))
((= state "instring") (cond
(escaping (progn
(setq curr-atom (strcat curr-atom ch))
(setq escaping F)))
((= ch "\\")
(progn
(setq ext (car jsonList))
(setq jsonList (cdr jsonList))
(cond
((= ext "\\") (setq curr-atom (strcat curr-atom "\\")))
((= ext "\"") (setq curr-atom (strcat curr-atom "\"")))
((= ext "/")(setq curr-atom (strcat curr-atom "/")))
((= ext "b")(setq curr-atom (strcat curr-atom (chr 8))))
((= ext "f")(setq curr-atom (strcat curr-atom (chr 12))))
((= ext "n")(setq curr-atom (strcat curr-atom (chr 10))))
((= ext "r")(setq curr-atom (strcat curr-atom (chr 13))))
((= ext "t")(setq curr-atom (strcat curr-atom (chr 9))))
((= ext "u")(progn
(setq curr-atom (strcat curr-atom (chr (readhex (take 4 jsonList)))))
(setq jsonList (drop 4 jsonList))
)))
))
((= ch string-delim)
(progn
(pop-state)
(pop-state)))
(T (setq curr-atom (strcat curr-atom ch)))
))
((= state "number") (cond
((or (isdigit ch) (= ch ".") (= ch "e") (= ch "E") (= ch "-") (= ch "+"))
(setq curr-atom (strcat curr-atom ch)))
(T (progn
(setq curr-atom (atof curr-atom))
(setq jsonList (cons ch jsonList))
(pop-state)
))
))
((= state "error") (skip))
(T (report-error (strcat "UnexpectedJSON parser state")))
))
(if (not (= state "error"))
(setq curr-atom curr-atom)
(progn
(princ (strcat error-message "\n"))
(setq curr-atom nil))
))
;(defun json:write (obj)
;...)
本帖最后由 landsat99 于 2022-4-24 11:04 编辑
Github另一位小哥的 Alisp-Json的读写函数。
The functions included in json_util.lsp:
_ json_to_list: Return a list with the elements of a string in json format
_ list_to_json: Return a string in json format from a list
;*************************************************************************************************
;* INICIO json_util.lsp
;*************************************************************************************************
;;-----------------------------------------------------------------------------------------
;;str_replace function.
;;Replace all aparisions of "patt" by "repl_to"
;;
;;Params:
;;-str: The original string
;;-patt: The pattern which will be replaced
;;-repl_to: The string which will replace the pattern
;;
;;Original Code by: diegomcas, 2020/03/25
;-----------------------------------------------------------------------------------------
(defun dmc:json:str_replace (str patt repl_to / pos inc init_search)
(if (not str) (setq str ""))
(if (and (not patt) (< (strlen patt) 1)) (setq patt " "))
(if (and (not repl_to) (< (strlen repl_to) 1)) (setq repl_to " "))
(setq pos (vl-string-search patt str))
(setq inc (1+ (- (strlen repl_to) (strlen patt))))
; (princ "pos= ") (princ pos) (princ "\n")
; (princ "inc= ") (princ inc) (princ "\n")
(while pos
(setq str (vl-string-subst repl_to patt str pos))
(setq init_search (+ pos inc))
(if (< init_search 0)
(setq init_search 0)
)
(setq pos (vl-string-search patt str init_search))
)
str
)
;;-----------------------------------------------------------------------------------------
;;json_parser function (To be executed by json_to_list)
;;Make a list of list with all data of the json string.
;;One list for each of:
;;-pairs name:value
;;-arrays
;;-objets
;;
;;Params:
;;-lst_json: The list prepared by (json_to_list) function
;;-state:for the use of the States Machine
;;
;;Original Code by: diegomcas, 2020/03/25
;;Modified 2021/03/09
;;-----------------------------------------------------------------------------------------
(defun dmc:json:json_parser (lst_json state array_lvl quote_array / lst str_name res)
(setq lst '())
(setq lst_pair '())
(if (not state)
(setq state 'Obj)
)
(if (not array_lvl)
(setq array_lvl 0)
)
(foreach res lst_json
; (princ "res= ") (princ res) (princ "\n")
; (princ "state= ") (princ state) (princ "\n")
; (princ "str_name= ") (princ str_name) (princ "\n")
; (princ "array_lvl= ") (princ array_lvl) (princ "\n")
; (princ "--------------------------------------------") (princ "\n")
(cond
;Case -> reading '<ARRAY>
((eq res (quote <ARRAY>))
(setq array_lvl (1+ array_lvl))
(setq state 'Array)
(if quote_array
(setq lst (append lst (list res)))
)
)
;Case -> reading '</ARRAY>
((eq res (quote </ARRAY>))
(setq array_lvl (1- array_lvl))
(setq state 'Obj)
(if quote_array
(setq lst (append lst (list res)))
)
)
;Case -> { null/true/false }
((and (eq state 'Obj) (or (eq res 'null) (eq res 'false) (eq res 'true)))
(setq lst (append lst (list res)))
)
;Case -> {name : value} / value = 'null or 'false or 'true or 'STR or 'INT or 'REAL
((and (eq state 'Obj_Value) (or (eq res 'null) (eq res 'false) (eq res 'true) (eq (type res) 'STR) (eq (type res) 'INT) (eq (type res) 'REAL)))
(if (eq 'STR (type res))
(progn
(setq res (dmc:json:str_replace res " , " "," ))
(setq res (dmc:json:str_replace res " : " ":" ))
(setq res (dmc:json:str_replace res "( <ARRAY> ""["))
(setq res (dmc:json:str_replace res " </ARRAY> )""]"))
)
)
(setq lst_pair (cons str_name res))
(setq lst (append lst (list lst_pair)))
(setq str_name nil)
)
;Case -> finish reading VALUE
((and (eq state 'Obj_Value) (eq res ',))
(setq state 'Obj)
)
;Case -> Reading a name {NAME : value}
((and (eq state 'Obj) (eq (type res) 'STR))
(setq res (dmc:json:str_replace res " , " "," ))
(setq res (dmc:json:str_replace res " : " ":" ))
(setq res (dmc:json:str_replace res "( <ARRAY> ""["))
(setq res (dmc:json:str_replace res " </ARRAY> )""]"))
(setq str_name res)
(setq state 'Obj_Name)
)
;Case -> Reading a new Object
((and (eq state 'Obj) (eq (type res) 'LIST))
(setq lst_temp (dmc:json:json_parser res state array_lvl quote_array))
(setq lst_pair (cons str_name lst_temp))
(setq lst (append lst (list lst_pair)))
)
;Case -> Reading a value = {Object}
((and (eq state 'Obj_Value) (eq (type res) 'LIST))
(setq lst_temp (dmc:json:json_parser res 'Obj array_lvl quote_array))
(if str_name
(setq lst_pair (cons str_name (list lst_temp)))
(setq lst_pair lst_temp)
)
(setq lst (append lst (list lst_pair)))
)
;Case -> Reading a complete name {NAME : value} -> Preparing to read value
((and (eq state 'Obj_Name) (eq res ':))
(setq state 'Obj_Value)
)
;Case -> Reading an Array
((and (eq state 'Array) (eq (type res) 'LIST))
(setq lst_temp (dmc:json:json_parser res nil array_lvl quote_array))
(if str_name
(setq lst_pair (cons str_name (list lst_temp)))
(setq lst_pair lst_temp)
)
(setq lst (append lst (list lst_pair)))
)
;Case -> ARRAY value = 'null or 'false or 'true or 'STR or 'INT or 'REAL without name
((and (and (> array_lvl 0) (eq state 'Array)) (or (eq res 'null) (eq res 'false) (eq res 'true) (eq (type res) 'STR) (eq (type res) 'INT) (eq (type res) 'REAL)))
; (princ res) (princ "\n")
(setq lst (append lst (list res)))
)
)
)
lst
)
;;-----------------------------------------------------------------------------------------
;;json_to_list function
;;Make a list of list with all data of the json string.
;;One list for each of:
;;-pairs name:value
;;-arrays
;;-objets
;;
;;Params:
;;-json: The json string (Strings values must not contain "(" ")")
;;
;;Original Code by: diegomcas, 2020/03/25
;;-----------------------------------------------------------------------------------------
(defun dmc:json:json_to_list (json quote_array / strtransf stread)
(if (not (eq 'STR (type json)))
(setq json "{}")
)
;Lists of lists for registers/arrays/objects of the json
(setq strtransf (vl-string-translate "{}" "()" json))
(setq strtransf (dmc:json:str_replace strtransf "[" "( <ARRAY> "))
(setq strtransf (dmc:json:str_replace strtransf "]" " </ARRAY> )"))
;add spaces before "," / Repairing bad read of numbers
(setq strtransf (dmc:json:str_replace strtransf "," " , "))
(setq strtransf (dmc:json:str_replace strtransf ":" " : "))
(setq stread (read strtransf))
;(princ "json -> ")(princ json) (princ "\n")
;(princ "stread -> ")(princ stread) (princ "\n")
(dmc:json:json_parser stread nil 0 quote_array)
)
;;-----------------------------------------------------------------------------------------
;;list_to_json function
;;Make a json string with all data of the json list.
;;
;;Not complete testing!!! Testing for use it!!!
;;Params:
;;-lst: The list of which will be written the json
;;
;;Autolisp don't have Arrays, so it is impossible to rebuild a json that contains them.
;;This function assume the list is Array Quote
;;
;;If you run (list_to_json (json_to_list "{your_json}"))
;;you probably lose data (type of data)
;;
;;Original Code by: diegomcas, 2020/03/25
;;Modified 2021/03/09
;;-----------------------------------------------------------------------------------------
(defun dmc:json:list_to_json (lst / lst_element json reading_val init_state value_to_string is_value is_attribute_simple is_attribute_complex is_array)
; (defun is_object (lst / )
; (and (eq (length lst) 2) (eq 'STR (type (car lst))) (not (is_array lst)))
; )
(defun value_to_string (element / )
(cond
((eq 'STR (type element))
(strcat "\"" element "\"")
)
((eq 'REAL (type element))
(rtos element 2 8)
)
((eq 'INT (type element))
(itoa element)
)
((eq 'NULL element)
"null"
)
((eq 'FALSE element)
"false"
)
((eq 'TRUE element)
"true"
)
)
)
(defun is_value (val / )
(or
(= (type val) 'STR)
(= (type val) 'REAL)
(= (type val) 'INT)
(= 'NULL val)
(= 'FALSE val)
(= 'TRUE val)
)
)
(defun is_attribute_simple (lst / )
(and (is_value (cdr lst)) (eq 'STR (type (car lst))) (not (is_array lst)))
)
(defun is_attribute_complex (lst / )
(and (= 'LIST (type (cdr lst))) (eq 'STR (type (car lst))) (not (is_array lst)))
)
(defun is_array (lst / res)
(eq (QUOTE <ARRAY>) (car lst))
)
(defun read_list (lst json state / )
(foreach lst_element lst
; (princ "---------------------------------------------------------\n")
; (princ "IN state -> ") (princ state) (princ "\n")
; (princ "lst_element -> ") (princ lst_element) (princ "\n")
(if (eq 'LIST (type lst_element)) ; Set of data
(progn
; (princ "Is LIST")(princ "\n")
(cond
; ARRAY -> Read any value (Objects, Arrays, strings, numbers, 'true, 'false, 'null)
((is_array lst_element)
; (princ "-> INIT ARRAY.") (princ "\n")
(setq reading_val nil)
(setq json (strcat json "["))
(setq json (read_list lst_element json 'ARRAY))
(setq json (strcat json "],"))
)
; ATTRIBUTES IN AN OBJECT
((is_attribute_complex lst_element)
; (princ "-> ATTRIBUTE COMPLEX IN AN OBJECT.") (princ "\n")
(setq reading_val nil)
; (princ "-> ATTRIBUTE complex.") (princ "\n")
(setq json (strcat json (value_to_string (car lst_element)) ":"))
(setq json (read_list (cdr lst_element) json 'OBJECT))
)
((is_attribute_simple lst_element)
(setq reading_val nil)
; (princ "-> ATTRIBUTE simple.") (princ "\n")
(setq json
(strcat
json
(value_to_string (car lst_element)) ":"
(value_to_string (cdr lst_element)) ","
)
)
)
; NO ARRAY / NO ATTRIBUTE -> Read Object
(T
; (princ "-> INIT OBJECT.") (princ "\n")
(setq reading_val nil)
(setq json (strcat json "{"))
(setq json (read_list lst_element json 'OBJECT))
(setq json (strcat json "},"))
)
)
)
(progn ;not is list / is name or value
; (princ "not is list / is name or value.") (princ "\n")
(if (not (or (eq lst_element '<ARRAY>) (eq lst_element '</ARRAY>)))
(cond
((eq state 'ARRAY)
(setq json (strcat json (value_to_string lst_element) ","))
)
((eq state 'ATTRIB)
(if reading_val
(progn
(setq json (strcat json (value_to_string lst_element) ","))
(setq reading_val nil)
)
(progn
(setq json (strcat json (value_to_string lst_element) ":"))
(setq reading_val T)
)
)
)
((eq state 'OBJECT)
)
)
)
)
)
; (princ "OUT state -> ") (princ state) (princ "\n")
; (princ "JSON -> ") (princ json) (princ "\n")
; (princ "---------------------------------------------------------\n")
)
json
)
(if (is_array lst)
(progn
(setq init_state 'ARRAY)
(setq init_string "[")
)
(progn
(setq init_state 'OBJECT)
(setq init_string "{")
)
)
(setq json (read_list lst init_string init_state))
(if (eq "[" init_string)
(setq json (strcat json "]"))
(setq json (strcat json "}"))
)
;Clean the string
(setq json (dmc:json:str_replace json ",}" "}"))
(setq json (dmc:json:str_replace json ",]" "]"))
)
;*************************************************************************************************
;* FIN json_util.lsp
;*************************************************************************************************
landsat99 发表于 2022-4-24 11:03
Github另一位小哥的 Alisp-Json的读写函数。
The functions included in json_util.lsp:
这个list转json的程序,出来的结果不对啊。
例如((1)(2)(3)),转出来是{{}{}{}},
字符都没有了
页:
[1]