[s-xml-devel] Getting XML attributes

Sven Van Caekenberghe scaekenberghe at common-lisp.net
Sun Nov 6 12:55:41 UTC 2005


Peter,

On 15 Oct 2005, at 11:05, Peter BARABAS wrote:

> Hello,
>
>
> Is there a way to get the attributes of an element via a specified
> "path"? E.g. something like:
>
> (let ((xml "<changelog><patch author='Peter BARABAS' local_date='Fri
> Apr 15 11:43:05 CEST 2005' inverted='False' <name>Added
> plan.</name></patch></changelog>"))
>   (get-xml-element "//changelog/patch/@local_date" xml))
>
> would return the string "Fri Apr 15 11:43:05 CEST 2005".
>
> A similar approach to get the text content of an element would be  
> useful,
>
> (get-text-element "//changelog/patch/name" xml)
>
> would return "Added plan.".
>
>
> Thank you for your help.
>
> --
> '(Yours parenthetically),
> peter barabas.
>
> ((call/cc call/cc) (call/cc call/cc))
> _______________________________________________


I somehow missed you question - sorry about that.

No, something like that does currently not exist in S-XML.
It would fit in one of the DOM packages I suppose.
If you convert XML to the LXML representation, for example,
it would not be too difficult to write some simple Lisp function to  
access the data you need.

These are for example some functions that I have been using (from the  
Cl-SOAP project):

(defun lxml-get-tag (lxml)
   "Return the XML tag symbol of the lxml XML DOM"
   (cond ((symbolp lxml) lxml)
         ((stringp lxml) '())
         ((symbolp (first lxml)) (first lxml))
         (t (first (first lxml)))))

(defun lxml-get-attributes (lxml)
   "Return the XML attributes plist of the lxml XML DOM"
   (cond ((or (symbolp lxml)
              (stringp lxml)
              (symbolp (first lxml))) '())
         (t (rest (first lxml)))))

(defun lxml-get-children (lxml)
   "Return the XML children list of the lxml XML DOM"
   (cond ((or (symbolp lxml)
              (stringp lxml)) '())
         (t (rest lxml))))

(defun lxml-get-contents (lxml)
   "Return the contents (first child) of the lxml XML DOM"
   (first (lxml-get-children lxml)))

(defun lxml-find-tag (tag lxml)
   "Find a specific tag in a lxml XML DOM list"
   (find tag lxml :key #'lxml-get-tag))

(defun lxml-find-tags (tag lxml)
   "Find all elements of a specific tag in a lxml XML DOM list"
   (remove-if-not #'(lambda (x) (eql (lxml-get-tag x) tag)) lxml))

Along these lines, you could add 'recursive drilling down' based on a  
'path' string.
Is there some standard for these 'path queries' ?

Contributions/extensions are allways welcome!

HTH,

Sven

--
Sven Van Caekenberghe - http://homepage.mac.com/svc
Beta Nine - software engineering - http://www.beta9.be

"Lisp isn't a language, it's a building material." - Alan Kay




More information about the s-xml-devel mailing list