This is a function intended to take an XML element (in closure XML format) and a name and find a piece of simple data by that name (either in a tag or attribute) within that XML element. It works, but I'm still new to LISP - can it be written more elegantly?
(defun find-data-inside-xml (element name)
;; Maybe there's an attribute?
(if (dom:has-attribute element name) (dom:get-attribute element name)
;; There isn't, we have to do it the ugly way. Find suitable subnodes.
(let ((candidate-values (loop for node across (dom:child-nodes element)
when (string= (dom:node-name node) name) collect node)))
;; Check there was only one of them.
(cond
((> (length candidate-values) 1) (error "XML element has multiple ~S elements." name))
((= (length candidate-values) 0) (error "XML element missing ~S element." name))
(t (let ((cand-children (dom:child-nodes (car candidate-values))))
;; Check the one there was, has only one child node.
(cond
((> (length cand-children) 1) (error "XML ~S element has complex content." name))
((= (length cand-children) 0) (error "~S element has no content." name))
(t (let ((content-node (elt cand-children 0)))
;; If that child node is text, that's our value. Otherwise, error.
(if (eq (dom:node-type content-node) :text)
(dom:node-value content-node)
(error "~S element value is not text." name)))))))))))