The first version of Ivan Shvedunov's Plexippus XPath has been released, an implementation of XPath 1.0, written entirely in Common Lisp.
Plexippus has been available from darcs for a few months now, and we have had some early users (thanks for testing the code at that early stage), but this is the first tarball release. New tarballs for cxml and its other add-on projects are also available now, so that you don't have to juggle with git, darcs, and CVS anymore.
Beta version: SBCL-only
Plexippus is well-tested on SBCL, but has not yet been ported to any other Lisp implementation. That's why this release is declared as a beta version.
(Ports to other Lisps mainly involve support code for non-trapping floating-point arithmetic. Patches are welcome.)
The XPath protocol
For extensibility, Plexippus defines a protocol of generic functions to implement the XPath data model, so any object model for XML can be queried using Plexippus if it implements these generic functions. Out-of-the-box, there is support for cxml-STP (a DOM alternative) and cxml's DOM.
Let's parse a test document first (no XPath involved yet):
CL-USER> (defparameter *document* (cxml:parse "<test a='1' b='2'> <child>hello world</child> </test>" (stp:make-builder))) *DOCUMENT*
Find and add the two attributes as numbers:
CL-USER> (xpath:evaluate "test/@a + test/@b" *document*) 3.0d0
Find the element called child and its string value. (Using string() in the expression itself would also have worked.)
CL-USER> (xpath:string-value (xpath:evaluate "//child" *document*)) "hello world"
Iterate over all elements, in document order:
CL-USER> (xpath:do-node-set (node (xpath:evaluate "//*" *document*)) (format t "found element: ~A~%" (xpath-protocol:local-name node))) found element: test found element: child