Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 477
  • Last Modified:

lisp: named parameters for structured data - lisp to xml conversion

Here's my simple LISP program for converting structured data to XML:

==============================
(defun strcat (&rest args)
  (apply #'concatenate
    (cons 'string args)))

(defun rectangle (x y width height color &rest children)
  (strcat
    "<rectangle"
      " x='" (princ-to-string x) "'"
      " y='" (princ-to-string y) "'"
      " width='" (princ-to-string width) "'"
      " height='" (princ-to-string height) "'"
      " color='" (princ-to-string color) "'"
    ">"
    (apply #'strcat children)
    "</rectangle>"
  )  
)

(print
  (rectangle 0 0 10 20 "blue"
    (rectangle 1 1 3 4 "green")
    (rectangle 5 1 3 4 "red")
  )
)
========================

Here's the output:

"<rectangle x='0' y='0' width='10' height='20' color='blue'><rectangle x='1' y='1' width='3' height='4' color='green'></rectangle><rectangle x='5' y='1' width='3' height='4' color='red'></rectangle></rectangle>"

However, I'd rather want the LISP program to use named parameters like this:

  (rectangle x: 0 y: 0 width: 10 height: 20 color: "blue"
    (rectangle x: 1 y: 1 width: 3 height: 4 color: "green")
    (rectangle x: 5 y: 1 width: 3 height: 4 color: "red")
  )

Sort-of like as described on
  http://per.bothner.com/papers/LispXML04/LispXML04.html

(taskbar
  (button label: "Back"
          image: left-arrow
          oncommand: back-command)
  (button label: "Next"
          image: right-arrow
          oncommand: next-command))

I've tried using "&key" in common lisp, but using it seems to require that all (not some) parameters be named.  Example:

  (defun foo (&rest rest &key a b c) (list rest a b c))
  (print (foo :a 1 :b 2 :c 3 1 2 3))

output error:

  *** - FOO: keyword arguments in (:A 1 :B 2 :C 3 1 2 3) should occur pairwise

I can do this:

  (defun foo (&rest rest) (list rest))
  (print (foo :a 1 :b 2 :c 3 1 2 3))

But, how does one bind and use the named parameters as in the original program.  Is there a convention for this?  Am I even on the right track?

Also, what is the difference between ":x" and "x:"?  The latter "looks" better in my code (the colon separates the attribute key and value), but the former seems more standard.
0
ext2
Asked:
ext2
  • 2
1 Solution
 
ext2Author Commented:
What I need is much like this:

LAML: Lisp Abstracted Markup Language
http://www.cs.aau.dk/~normark/laml/
0
 
ext2Author Commented:
[[Request for refund of points]]

I think I've figured this all out.  The essential idea was to just use &rest (and not use &key) as such:

  (defun foo (&rest lst)
    (list "foo" (atts lst) (elements lst))
  )

and then write one's own code to extract the attributes and elements from lst:

;; extract attributes from list
(defun atts (lst)
  (cond
    ((null  (first  lst)) '())  ;; done
    ((listp (first  lst)) (atts (rest lst)))  ;; found element (ignore)
    ((null  (second lst)) nil) ;; error
    ((and (atom (first  lst))  ;; found attribute
          (atom (second lst)))
            (cons (list (first lst) (second lst))
                  (atts (rest (rest lst)))
    ))
    (t nil) ;; error
  )
)

;; extract elements from list
(defun elements (lst)
  (cond
    ((null  (first lst)) '()) ;; done
    ((listp (first lst)) (cons (first lst) (elements (rest lst)))) ;; found element
    (t (elements (rest (rest lst)))) ;; found attribute or error (ignore)
  )
)

One can follow the same design as in LAML of generating the abstract syntax tree (AST) and then serializing it as XML.
0
 
EE_AutoDeleterCommented:
ext2,
Because you have presented a solution to your own problem which may be helpful to future searches, this question is now PAQed and your points have been refunded.

EE_AutoDeleter
0

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now