- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hello All,
As somebody who feels comfortable with lisp and has yet to gain such familiarity in a couple other languages, I have tried to really explore my limits with the language. With APIs being SO HUGE these days, I find myself more-and-more seeking ways to implement them at work, where feasible, to make my workflows easier (especially since we still use "vanilla" AutoCAD). While there may be more effective / efficient ways to call APIs with either this language or others, I wanted to get this out there for others who may want to get their feet in the door.
Here is one method for you to easily call out to an API that returns JSON data, convert that information to a List, then easily manipulate it. This method clearly requires that you have the ActiveX extended functions installed via (vl-load-com). Please note, that no error checking of the actual JSON data has been included. If an error is returned by your API, you will need to account for that.
If anyone has better or other methods for lisp, please don't hesitate to share..
(defun GetFromWeb (strUrl / webObj stat res errobj) ;Code posted by user: BazzaCAD, 2010/03/29, from site: ;http://opendcl.com/forum/index.php?topic=1244.0 (vl-load-com) ;; Set up variables (setq webObj nil stat nil res nil) ;; Create a new reference to the WinHttp object (setq webObj (vlax-invoke-method (vlax-get-acad-object) 'GetInterfaceObject "WinHttp.WinHttpRequest.5.1")) ;; Fetch web page (vlax-invoke-method webObj 'Open "GET" strUrl :vlax-false) (setq errobj (vl-catch-all-apply 'vlax-invoke-method (list webObj 'Send))) (if (null (vl-catch-all-error-p errobj)) (progn (setq stat (vlax-get-property webObj 'Status)) (if (= stat 200) (progn (setq res (vlax-get-property webObj 'ResponseText));_ Return the response value // 'ResponseText ) (princ (strcat "\n!!! WEB server error: " (vlax-get-property webObj 'StatusText) "!!!")) ) );_ progn (princ (strcat "\n!!! WEB server error:\n" (vl-catch-all-error-message errobj))) ) res );defun (defun JSON->LIST (json / ) ;json - string, as json data ;returns - list, converted from json (if (eq 'STR (type json)) (read (vl-string-translate "[]{}:," "()() " json))) );defun (defun LIST->PAIRS (lst / ret tmp) ;this function is recursive ;lst - list, the list returned by "JSON->LIST", or similar ;returns - dotted pair lists or, in the case of nested lists, lists similar to points found in entities (item val1 val2 ...) (setq ret '()) (if (listp lst) (foreach i lst (if (listp i) (setq ret (cons (list (LIST->PAIRS i)) ret)) (if (eq 0 (rem (length (member i lst)) 2)) (setq ret (cons (cons i (if (listp (setq tmp (cadr (member i lst)))) (LIST->PAIRS tmp) tmp)) ret)) );if );if );foreach ;else (setq ret "") );if (reverse ret) );defun (defun c:CALL ( / url data) (vl-load-com) ;this url is open to everybody, it contains example data for anybody to test (setq url "https://jsonplaceholder.typicode.com/users") (if (and (setq data (GetFromWeb url)) (setq data (JSON->LIST data))) (progn ;now that we have a list, manipulate however you want ;Here is the entire list (all json data) (prompt "\n---Here is the JSON->LIST list---\n") (princ data) (prompt "\n---------------------------------\n") ;we can use our list manipulation functions to get specific items ;for example, we can loop through all users and print their names & emails (prompt "\n---Here are the names & emails---\n") (mapcar '(lambda (user) (princ (strcat "\nName: " (cadr (member "name" user)) " // Email: " (cadr (member "email" user))))) data) (prompt "\n---------------------------------\n") ;sometimes it may be more useful to have "assoc" pairs to work with (prompt "\n---Here is the LIST->PAIRS list--\n") (princ (setq data (LIST->PAIRS data))) (prompt "\n---------------------------------\n") (prompt "\nCALL Complete...") );progn ;else (prompt "\nError Getting / Converting JSON data.") );if (princ) );defun
Best,
~DD
Solved! Go to Solution.