I am looking for easy access to small XML files. I came up with the following... Being new to newLISP and Lisp in general, I am sure someone can make the function a bit nicer. Just seems kind of, I don't know, kludgey?
Any criticism would be appriciated. Does anyone have better methods at easy access to a parsed xml file?
Jeremy
(define (my-xml-parse filename)
(xml-type-tags nil nil nil nil)
(rest (first (xml-parse (read-file filename) (+ 1 2 4 8 16)))))
(define (xml-get path data)
(let (p (parse path {/}))
(for (c 0 (- (length p) 1))
(let (loc (first (ref (sym (nth c p)) data)))
(set 'data (nth loc data)))))
(rest data))
(set 'config (my-xml-parse "config.xml"))
(println (xml-get (main-args 2) config))
(exit)
; config.xml:
; <config>
; <name><first>John</first><last>Doe</last></name>
; <age>20</age>
; <friends>
; <name>Jane</name>
; <name>Joe</name>
; <name>Frank</name>
; </friends>
; </config>
;
; $ newlisp config.lsp name/first
; ("John")
; $ newlisp config.lsp friends
; ((name "Jane") (name "Joe") (name "Frank"))
It looks OK to me! I'm not very good at 'criticizing' code. But in newLISP there's nearly always a more elegant way of doing things, even if you can't find it yourself. You can usually throw the first effort away - once you know it's possible, then it's a question of doing it well. (If you've got the time, of course. :-)
For example, a slight rewrite:
(define (xml-get path data)
(let (path-item (parse path {/})
(section data))
(dolist (element path-item)
(set 'section (section (chop (ref (sym element) section)))))
(rest section)))
but it's only slightly different. And not very neat, either - too many occurrences of that 'section'? No error handling either...;-)
By the way, this only worked when the xml-parse options were (+ 1 2 4 8). With 16, I kept getting errors - I don't like the look of the 16 option.