3

From JSON, I'm trying to build a nested list of nodes which should look like the expected result below:

(html (head (meta title)) (body (ul (div) (div) (div))) ; I guess this is the right approach for an interface label

This is the original data from json-read-from-string:

(pp json-dom)
((tag . "html")
 (children .
           [((tag . "head")
             (children .
                       [((tag . "meta")
                         (children .
                                   []))
                        ((tag . "title")
                         (children .
                                   []))]))
            ((tag . "body")
             (children .
                       [((tag . "ul")
                         (children .
                                   [((tag . "div")
                                     (children .
                                               []))
                                    ((tag . "div")
                                     (children .
                                               []))
                                    ((tag . "div")
                                     (children .
                                               []))]))                                               
                        ]))]))

I will be grateful if you can please assist in helping to obtain the correct result.

This is what I have done so far:

Starting with the recursive function, I'm faced with either invalid argument when testing with listp or nil result when testing the top argument with vectorp

(defun sidetree (node) 
  (when (vectorp node) 
    (cons (cdr (assoc 'tag node)) 
          (sidetree 
            (assoc 'children node)
            ; (cdr (car (aref (cdr (assoc 'children json-dom)) 0)))
            ))))

(pp (sidetree json-dom))
nil"nil"

I tried using the letrec approach as well,

(defun fliptree()
  (letrec
      ((untree (lambda (tr)
                  (list
                  (alist-get 'tag tr)
                  (append (apply-partially untree '(alist-get 'children node)) nil )
                  ))))
    (funcall untree json-dom)))

And got the following result. I don't know what I'm not doing right.

(pp (fliptree))
("html"
  (128 "\302\300\303\301\"\"\207"
      [(closure
            ((untree closure #4
                    (tr)
                    (list
                      (alist-get 'tag tr)
                      (append
                      (apply-partially untree
                                        '(alist-get 'children node))
                      nil)))
            t)
            (tr)
          (list
          (alist-get 'tag tr)
          (append
            (apply-partially untree
                            '(alist-get 'children node))
            nil)))
        ((alist-get 'children node))
        apply append]
      6 "\n\n(fn &rest ARGS2)"))
​
​
​
Drew
  • 75,699
  • 9
  • 109
  • 225
alexander
  • 135
  • 6

1 Answers1

4

We can get 'more or less' the result that you want using the following function:

(defun json-format (obj)
  (when obj
      (cons (let ((rest (cdr (car obj))))
              (if (vectorp rest)
                  (map 'list #'json-format rest)
                (intern rest)))
            (unless (= (length (cdadr obj)) 0)
              (car (json-format (cdr obj)))))))

Calling it with the data (where data is you 'original data'), (json-format data), returns the following:

(html (head (meta) (title)) (body (ul (div) (div) (div))))
dalanicolai
  • 6,108
  • 7
  • 23