chickadee » sxpath » sxpath

sxpath path #!optional ns-bindingprocedure

Returns a procedure that accepts an SXML document tree and an optional association list of variables and returns a nodeset (list of nodes) that match the path expression.

The optional ns-binding argument is an alist of namespace bindings. It is used to map abbreviated namespace prefixes to full URI strings but only for textual XPath strings embedded in the path expression.

The optional association list of variables must include all the variables defined by the sxpath expression.

The path is translated to the full SXPath according to the following rewriting rules:

; (sxpath '()) -> (node-join)
; (sxpath '(path-component ...)) ->
;		(node-join (sxpath1 path-component) (sxpath '(...)))
; (sxpath1 '//) -> (sxml:descendant-or-self sxml:node?)
; (sxpath1 '(equal? x)) -> (select-kids (node-equal? x))
; (sxpath1 '(eq? x))    -> (select-kids (node-eq? x))
; (sxpath1 '(*or* ...))  -> (select-kids (ntype-names??
;                                          (cdr '(*or* ...))))
; (sxpath1 '(*not* ...)) -> (select-kids (sxml:complement 
;                                         (ntype-names??
;                                          (cdr '(*not* ...)))))
; (sxpath1 '(ns-id:* x)) -> (select-kids 
;                                      (ntype-namespace-id?? x))
; (sxpath1 ?symbol)     -> (select-kids (ntype?? ?symbol))
; (sxpath1 ?string)     -> (txpath ?string)
; (sxpath1 procedure)   -> procedure
; (sxpath1 '(?symbol ...)) -> (sxpath1 '((?symbol) ...))
; (sxpath1 '(path reducer ...)) ->
;		(node-reduce (sxpath path) (sxpathr reducer) ...)
; (sxpathr number)      -> (node-pos number)
; (sxpathr path-filter) -> (filter (sxpath path-filter))

It can be useful to compare the following examples to those for txpath.

(import sxpath)

;; selects all the 'item' elements that have an 'olist' parent
;; (which is not root) and that are in the same document as the context node
((sxpath `(// olist item))
 '(doc (olist (item "1")) (item "2") (nested (olist (item "3")))))
 => ((item "1") (item "3"))


(import sxpath-lolevel (chicken base))

;; selects only the nth 'item' element under each 'olist' parent
;; (which is not root) and that is in the same document as the context node
;; The n is parameterized to be the first item
;; The node-pos function comes from sxpath-lolevel and implements txpath position selector [$n]
((sxpath `(// olist ((item ,(lambda (nodeset var-binding) ((node-pos (alist-ref 'n var-binding)) nodeset))))))
 '(doc (olist (item "1") (item "2")) (nested (olist (item "3")))) '((n . 1)))
 => ((item "1") (item "3"))

;; selects the 'chapter' children of the context node that have one or
;; more 'title' children with string-value equal to 'Introduction'
((sxpath '((chapter ((equal? (title "Introduction"))))))
 '(text  (chapter (title "Introduction"))  (chapter "No title for this chapter")  (chapter (title "Conclusion"))))
 => ((chapter (title "Introduction")))

;; (sxpath string-expr) is equivalent to (txpath string-expr)
((sxpath "chapter[title='Introduction']")
 '(text  (chapter (title "Introduction"))  (chapter "No title for this chapter")  (chapter (title "Conclusion"))))
 => ((chapter (title "Introduction")))