#cs(module txpath mzscheme
(require (lib "string.ss" "srfi/13"))
(require (planet "ssax.ss" ("lizorkin" "ssax.plt" 2 0)))
(require "sxml-tools.ss")
(require "sxpath-ext.ss")
(require "xpath-parser.ss")
(define (sxml:xpointer-runtime-error . text)
(apply cerr (append (list "XPath/XPointer runtime error: ") text (list nl)))
(exit -1))
(define (sxml:xpath-nodeset-filter preds-list nodeset root-node var-binding)
(let rpt ((nodeset nodeset)
(ps preds-list))
(if (null? ps)
nodeset
(let lab ((nset nodeset)
(res '())
(pos 1))
(if (null? nset)
(rpt (reverse res) (cdr ps))
(let* ((size (length nodeset))
(val ((car ps)
(list (car nset))
root-node
(cons pos size)
var-binding)))
(lab (cdr nset)
(if (if (number? val)
(= val pos)
(sxml:boolean val))
(cons (car nset) res)
res)
(+ pos 1))))))))
(define (sxml:arithmetic-eval unary-expr-res-lst op-lst add-on)
(lambda (nodeset root-node context var-binding)
(let rpt
((res (sxml:number
((car unary-expr-res-lst) nodeset root-node context var-binding)))
(fs (cdr unary-expr-res-lst))
(ops op-lst))
(if (null? fs)
res
(rpt ((car ops)
res
(sxml:number ((car fs) nodeset root-node context var-binding)))
(cdr fs)
(cdr ops))))))
(define (sxml:core-last)
(lambda (nodeset root-node context var-binding)
(cdr context)))
(define (sxml:core-position)
(lambda (nodeset root-node context var-binding)
(car context)))
(define (sxml:core-count arg-func)
(lambda (nodeset root-node context var-binding)
(let ((res (arg-func nodeset root-node context var-binding)))
(cond
((nodeset? res) (length res))
(else
(sxml:xpointer-runtime-error
"count() function - an argument is not a nodeset")
0)))))
(define (sxml:core-id arg-func)
(lambda (nodeset root-node context var-binding)
(let* ((id-nset ((sxml:child (ntype?? 'id-index))
((sxml:child (ntype?? '@@)) root-node))))
(if
(null? id-nset) '() ((sxml:id (cdar id-nset)) (arg-func nodeset root-node context var-binding))))))
(define (sxml:core-local-name . arg-func) (if (null? arg-func) (lambda (nodeset root-node context var-binding)
(cond
((null? nodeset) "")
((not (pair? (car nodeset))) "") (else
(let ((name (symbol->string (caar nodeset))))
(cond
((string-rindex name #\:)
=> (lambda (pos)
(substring name (+ pos 1) (string-length name))))
(else name))))))
(let ((func (car arg-func)))
(lambda (nodeset root-node context var-binding)
(let ((obj (func nodeset root-node context var-binding)))
(cond
((null? obj) "") ((not (nodeset? obj))
(sxml:xpointer-runtime-error
"NAME function - an argument is not a nodeset")
"")
((not (pair? (car obj))) "") (else
(let ((name (symbol->string (caar obj))))
(cond
((string-rindex name #\:)
=> (lambda (pos)
(substring
name (+ pos 1) (string-length name))))
(else name))))))))))
(define (sxml:core-namespace-uri . arg-func) (if (null? arg-func) (lambda (nodeset root-node context var-binding)
(cond
((null? nodeset) "")
((not (pair? (car nodeset))) "") (else
(let ((name (symbol->string (caar nodeset))))
(cond
((string-rindex name #\:)
=> (lambda (pos)
(substring name 0 pos)))
(else "")))))) (let ((func (car arg-func)))
(lambda (nodeset root-node context var-binding)
(let ((obj (func nodeset root-node context var-binding)))
(cond
((null? obj) "") ((not (nodeset? obj))
(sxml:xpointer-runtime-error
"NAME function - an argument is not a nodeset")
"")
((not (pair? (car obj))) "") (else
(let ((name (symbol->string (caar obj))))
(cond
((string-rindex name #\:)
=> (lambda (pos)
(substring name 0 pos)))
(else ""))))))))))
(define (sxml:core-name . arg-func) (if (null? arg-func) (lambda (nodeset root-node context var-binding)
(cond
((null? nodeset) "")
((not (pair? (car nodeset))) "") (else
(symbol->string (caar nodeset)))))
(let ((func (car arg-func)))
(lambda (nodeset root-node context var-binding)
(let ((obj (func nodeset root-node context var-binding)))
(cond
((null? obj) "") ((not (nodeset? obj))
(sxml:xpointer-runtime-error
"NAME function - an argument is not a nodeset")
"")
((not (pair? (car obj))) "") (else
(symbol->string (caar obj)))))))))
(define (sxml:core-string . arg-func) (if (null? arg-func) (lambda (nodeset root-node context var-binding)
(sxml:string nodeset))
(let ((func (car arg-func)))
(lambda (nodeset root-node context var-binding)
(sxml:string
(func nodeset root-node context var-binding))))))
(define (sxml:core-concat . arg-func-lst)
(lambda (nodeset root-node context var-binding)
(apply
string-append
(map
(lambda (f)
(sxml:string (f nodeset root-node context var-binding)))
arg-func-lst))))
(define (sxml:core-starts-with arg-func1 arg-func2)
(lambda (nodeset root-node context var-binding)
(let ((str1 (sxml:string
(arg-func1 nodeset root-node context var-binding)))
(str2 (sxml:string
(arg-func2 nodeset root-node context var-binding))))
(string-prefix? str2 str1))))
(define (sxml:core-contains arg-func1 arg-func2)
(lambda (nodeset root-node context var-binding)
(let ((str1 (sxml:string
(arg-func1 nodeset root-node context var-binding)))
(str2 (sxml:string
(arg-func2 nodeset root-node context var-binding))))
(if (substring? str2 str1) #t #f) )))
(define (sxml:core-substring-before arg-func1 arg-func2)
(lambda (nodeset root-node context var-binding)
(let* ((str1 (sxml:string
(arg-func1 nodeset root-node context var-binding)))
(str2 (sxml:string
(arg-func2 nodeset root-node context var-binding)))
(pos (substring? str2 str1)))
(if (not pos) ""
(substring str1 0 pos)))))
(define (sxml:core-substring-after arg-func1 arg-func2)
(lambda (nodeset root-node context var-binding)
(let* ((str1 (sxml:string
(arg-func1 nodeset root-node context var-binding)))
(str2 (sxml:string
(arg-func2 nodeset root-node context var-binding)))
(pos (substring? str2 str1)))
(if
(not pos) ""
(substring
str1 (+ pos (string-length str2)) (string-length str1))))))
(define (sxml:core-substring arg-func1 arg-func2 . arg-func3)
(if (null? arg-func3) (lambda (nodeset root-node context var-binding)
(let ((str (sxml:string
(arg-func1 nodeset root-node context var-binding)))
(num1 (sxml:number
(arg-func2 nodeset root-node context var-binding))))
(let ((len (string-length str))
(start (- (inexact->exact (round num1)) 1)))
(if (> start len)
""
(substring str (if (< start 0) 0 start) len)))))
(let ((arg-func3 (car arg-func3)))
(lambda (nodeset root-node context var-binding)
(let ((str (sxml:string
(arg-func1 nodeset root-node context var-binding)))
(num1 (sxml:number
(arg-func2 nodeset root-node context var-binding)))
(num2 (sxml:number
(arg-func3 nodeset root-node context var-binding))))
(let* ((len (string-length str))
(start (- (inexact->exact (round num1)) 1))
(fin (+ start (inexact->exact (round num2)))))
(if (or (> start len) (< fin 0) (< fin start))
""
(substring str
(if (< start 0) 0 start)
(if (> fin len) len fin)))))))))
(define (sxml:core-string-length . arg-func) (if (null? arg-func) (lambda (nodeset root-node context var-binding)
(string-length (sxml:string nodeset)))
(let ((func (car arg-func)))
(lambda (nodeset root-node context var-binding)
(string-length
(sxml:string
(func nodeset root-node context var-binding)))))))
(define (sxml:core-normalize-space . arg-func) (if (null? arg-func) (lambda (nodeset root-node context var-binding)
(let rpt ((src (string-split (sxml:string nodeset) sxml:whitespace))
(res '()))
(cond
((null? src)
(apply string-append (reverse res)))
((= (string-length (car src)) 0) (rpt (cdr src) res))
((null? res)
(rpt (cdr src) (cons (car src) res)))
(else
(rpt (cdr src) (cons (car src) (cons " " res)))))))
(let ((func (car arg-func)))
(lambda (nodeset root-node context var-binding)
(let rpt ((src (string-split
(sxml:string
(func nodeset root-node context var-binding))
sxml:whitespace))
(res '()))
(cond
((null? src)
(apply string-append (reverse res)))
((= (string-length (car src)) 0) (rpt (cdr src) res))
((null? res)
(rpt (cdr src) (cons (car src) res)))
(else
(rpt (cdr src) (cons (car src) (cons " " res))))))))))
(define (sxml:core-translate arg-func1 arg-func2 arg-func3)
(lambda (nodeset root-node context var-binding)
(let ((str1 (sxml:string
(arg-func1 nodeset root-node context var-binding)))
(str2 (sxml:string
(arg-func2 nodeset root-node context var-binding)))
(str3 (sxml:string
(arg-func3 nodeset root-node context var-binding))))
(let ((alist
(let while ((lst2 (string->list str2))
(lst3 (string->list str3))
(alist '()))
(cond
((null? lst2) (reverse alist))
((null? lst3)
(append
(reverse alist)
(map
(lambda (ch) (cons ch #f))
lst2)))
(else
(while
(cdr lst2)
(cdr lst3)
(cons (cons (car lst2) (car lst3)) alist)))))))
(let rpt ((lst1 (string->list str1))
(res '()))
(cond
((null? lst1) (list->string (reverse res)))
((assoc (car lst1) alist)
=> (lambda (pair)
(if (cdr pair)
(rpt (cdr lst1) (cons (cdr pair) res))
(rpt (cdr lst1) res))))
(else
(rpt (cdr lst1) (cons (car lst1) res)))))))))
(define (sxml:core-boolean arg-func)
(lambda (nodeset root-node context var-binding)
(sxml:boolean
(arg-func nodeset root-node context var-binding))))
(define (sxml:core-not arg-func)
(lambda (nodeset root-node context var-binding)
(not (sxml:boolean
(arg-func nodeset root-node context var-binding)))))
(define (sxml:core-true)
(lambda (nodeset root-node context var-binding) #t))
(define (sxml:core-false)
(lambda (nodeset root-node context var-binding) #f))
(define (sxml:core-lang arg-func)
(lambda (nodeset root-node context var-binding)
(if
(null? nodeset)
#f
(let ((arg (sxml:string
(arg-func nodeset root-node context var-binding)))
(context-node (car nodeset)))
(let rpt ((pairs
(map
(lambda (node) (cons node #f))
root-node)))
(if
(null? pairs) #f
(let* ((lng
((sxml:child (ntype?? '*text*))
((sxml:attribute (ntype?? 'xml:lang))
(caar pairs))))
(lng (if (null? lng) (cdar pairs) (car lng))))
(if
(eq? context-node (caar pairs)) (and
lng
(or (string-ci=? arg lng)
(string-prefix-ci? (string-append arg "-") lng)))
(rpt
(append
(map
(lambda (node) (cons node lng))
((sxml:attribute (ntype?? '*)) (caar pairs)))
(map
(lambda (node) (cons node lng))
((sxml:child sxml:node?) (caar pairs)))
(cdr pairs)))))))))))
(define (sxml:core-number . arg-func) (if (null? arg-func) (lambda (nodeset root-node context var-binding)
(sxml:number nodeset))
(let ((func (car arg-func)))
(lambda (nodeset root-node context var-binding)
(sxml:number
(func nodeset root-node context var-binding))))))
(define (sxml:core-sum arg-func)
(lambda (nodeset root-node context var-binding)
(let ((res (arg-func nodeset root-node context var-binding)))
(cond
((nodeset? res)
(apply +
(map
(lambda (node)
(sxml:number (sxml:string-value node)))
res)))
(else
(sxml:xpointer-runtime-error
"SUM function - an argument is not a nodeset")
0)))))
(define (sxml:core-floor arg-func)
(lambda (nodeset root-node context var-binding)
(inexact->exact
(floor (sxml:number
(arg-func nodeset root-node context var-binding))))))
(define (sxml:core-ceiling arg-func)
(lambda (nodeset root-node context var-binding)
(inexact->exact
(ceiling (sxml:number
(arg-func nodeset root-node context var-binding))))))
(define (sxml:core-round arg-func)
(lambda (nodeset root-node context var-binding)
(inexact->exact
(round (sxml:number
(arg-func nodeset root-node context var-binding))))))
(define sxml:classic-params
`(
(axis
((ancestor
,(lambda (add-on) (cons sxml:ancestor #t)))
(ancestor-or-self
,(lambda (add-on) (cons sxml:ancestor-or-self #t)))
(attribute
,(lambda (add-on) (cons sxml:attribute #f)))
(child
,(lambda (add-on) (cons sxml:child #f)))
(descendant
,(lambda (add-on) (cons sxml:descendant #f)))
(descendant-or-self
,(lambda (add-on) (cons sxml:descendant-or-self #f)))
(following
,(lambda (add-on) (cons sxml:following #t)))
(following-sibling
,(lambda (add-on) (cons sxml:following-sibling #t)))
(namespace
,(lambda (add-on) (cons sxml:namespace #f)))
(parent
,(lambda (add-on) (cons sxml:parent #t)))
(preceding
,(lambda (add-on) (cons sxml:preceding #t)))
(preceding-sibling
,(lambda (add-on) (cons sxml:preceding-sibling #t)))
(self
,(lambda (add-on) (cons sxml:filter #f)))))
(node-test
((star
,(lambda (add-on) (ntype?? '*)))
(uri+star
,(lambda (uri add-on) (ntype-namespace-id?? uri)))
(qname
,(lambda (uri local-name add-on)
(if (not uri)
(ntype?? (string->symbol local-name))
(ntype?? (string->symbol (string-append uri ":" local-name))))))
(comment
,(lambda (add-on) (ntype?? '*COMMENT*)))
(text
,(lambda (add-on) (ntype?? '*text*)))
(processing-instruction
,(lambda (literal-string add-on)
(if (not literal-string) (lambda (node)
(and (pair? node) (eq? (car node) '*PI*)))
(let ((literal (string->symbol literal-string)))
(lambda (node)
(and (pair? node)
(eq? (car node) '*PI*)
(equal? (cadr node) literal)))))))
(node
,(lambda (add-on) sxml:node?))
(point
,(lambda (add-on)
(txp:signal-semantic-error
"point() NodeTest is not supported by this implementation")))
(range
,(lambda (add-on)
(txp:signal-semantic-error
"range() NodeTest is not supported by this implementation")))))
(step
((common
,(lambda (axis-res node-test-res predicate-res-lst add-on)
(let ((axis (car axis-res))
(root-node-required (cdr axis-res)))
(if
(null? predicate-res-lst)
(lambda (nodeset root-node context var-binding)
(if root-node-required
(((axis node-test-res) root-node) nodeset)
((axis node-test-res) nodeset)))
(lambda (nodeset root-node context var-binding)
(map-union
(lambda (node)
(sxml:xpath-nodeset-filter
predicate-res-lst
((if root-node-required
((axis node-test-res) root-node)
(axis node-test-res))
node)
root-node var-binding))
nodeset))))))
(range-to
,(lambda (expr-res predicate-res-lst add-on)
(txp:signal-semantic-error "range-to function not implemented")))))
(relative-lpath
,(lambda (step-res-lst add-on)
(if
(null? (cdr step-res-lst)) (car step-res-lst)
(lambda (nodeset root-node context var-binding)
(let rpt ((nset nodeset)
(fs step-res-lst))
(if (null? fs)
nset
(rpt ((car fs) nset root-node context var-binding)
(cdr fs))))))))
(location-path
((bare-slash
,(lambda (add-on)
(lambda (nodeset root-node context var-binding) root-node)))
(slash
,(lambda (relative-lpath-res add-on)
(lambda (nodeset root-node context var-binding)
(relative-lpath-res root-node root-node context var-binding))))
(double-slash
,(lambda (relative-lpath-res add-on)
(lambda (nodeset root-node context var-binding)
(relative-lpath-res
((sxml:descendant-or-self sxml:node?) root-node)
root-node context var-binding))))))
(predicate
,(lambda (expr-res add-on) expr-res))
(variable-ref
,(lambda (var-name-string add-on)
(let ((name (string->symbol var-name-string)))
(lambda (nodeset root-node context var-binding)
(cond
((assoc name var-binding)
=> cdr)
(else
(sxml:xpointer-runtime-error "unbound variable - " name)
'()))))))
(function-call
,(lambda (fun-name-string arg-res-lst add-on)
(let ((core-alist
`((last 0 0 ,sxml:core-last)
(position 0 0 ,sxml:core-position)
(count 1 1 ,sxml:core-count)
(id 1 1 ,sxml:core-id)
(local-name 0 1 ,sxml:core-local-name)
(namespace-uri 0 1 ,sxml:core-namespace-uri)
(name 0 1 ,sxml:core-name)
(string 0 1 ,sxml:core-string)
(concat 2 -1 ,sxml:core-concat)
(starts-with 2 2 ,sxml:core-starts-with)
(contains 2 2 ,sxml:core-contains)
(substring-before 2 2 ,sxml:core-substring-before)
(substring-after 2 2 ,sxml:core-substring-after)
(substring 2 3 ,sxml:core-substring)
(string-length 0 1 ,sxml:core-string-length)
(normalize-space 0 1 ,sxml:core-normalize-space)
(translate 3 3 ,sxml:core-translate)
(boolean 1 1 ,sxml:core-boolean)
(not 1 1 ,sxml:core-not)
(true 0 0 ,sxml:core-true)
(false 0 0 ,sxml:core-false)
(lang 1 1 ,sxml:core-lang)
(number 0 1 ,sxml:core-number)
(sum 1 1 ,sxml:core-sum)
(floor 1 1 ,sxml:core-floor)
(ceiling 1 1 ,sxml:core-ceiling)
(round 1 1 ,sxml:core-round))))
(cond
((assq (string->symbol fun-name-string) core-alist)
=> (lambda (quad) (cond
((< (length arg-res-lst) (cadr quad))
(txp:signal-semantic-error
"too few arguments for the Core Function call - "
fun-name-string))
((and (> (caddr quad) 0)
(> (length arg-res-lst) (caddr quad)))
(txp:signal-semantic-error
"too many arguments for the Core Function call - "
fun-name-string))
(else (apply (cadddr quad) arg-res-lst)))))
(else (txp:signal-semantic-error
"function call to an unknown function - " fun-name-string))))))
(primary-expr
((literal
,(lambda (literal add-on)
(lambda (nodeset root-node context var-binding) literal)))
(number
,(lambda (number add-on)
(lambda (nodeset root-node context var-binding) number)))))
(filter-expr
,(lambda (primary-expr-res predicate-res-lst add-on)
(lambda (nodeset root-node context var-binding)
(let ((nodeset
(primary-expr-res nodeset root-node context var-binding)))
(sxml:xpath-nodeset-filter
predicate-res-lst
(cond
((nodeset? nodeset) nodeset)
(else
(sxml:xpointer-runtime-error
"expected - nodeset instead of " nodeset)
'()))
root-node var-binding)))))
(path-expr
((slash
,(lambda (filter-expr-res relative-lpath-res add-on)
(lambda (nodeset root-node context var-binding)
(let ((nset
(filter-expr-res nodeset root-node context var-binding)))
(let ((nset
(cond
((nodeset? nset) nset)
(else
(sxml:xpointer-runtime-error
"expected - nodeset instead of " nset)
'()))))
(relative-lpath-res nset root-node context var-binding))))))
(double-slash
,(lambda (filter-expr-res relative-lpath-res add-on)
(lambda (nodeset root-node context var-binding)
(let ((nset
(filter-expr-res nodeset root-node context var-binding)))
(let ((nset
(cond
((nodeset? nset) nset)
(else
(sxml:xpointer-runtime-error
"expected - nodeset instead of " nset)
'()))))
(let ((nset ((sxml:descendant-or-self sxml:node?) nset)))
(relative-lpath-res
nset root-node context var-binding)))))))))
(union-expr
,(lambda (path-expr-res-lst add-on)
(lambda (nodeset root-node context var-binding)
(let rpt ((res '())
(fs path-expr-res-lst))
(if
(null? fs)
res
(let ((nset ((car fs) nodeset root-node context var-binding)))
(rpt
(append
res
(cond
((not (nodeset? nset))
(sxml:xpointer-runtime-error
"expected - nodeset instead of " nset)
'())
(else nset)))
(cdr fs))))))))
(unary-expr
,(lambda (union-expr-res num-minuses add-on)
(if (even? num-minuses)
(lambda (nodeset root-node context var-binding)
(sxml:number
(union-expr-res nodeset root-node context var-binding)))
(lambda (nodeset root-node context var-binding)
(- (sxml:number
(union-expr-res nodeset root-node context var-binding)))))))
(operations
((* ,(lambda (add-on) *))
(div ,(lambda (add-on) /))
(mod ,(lambda (add-on) remainder))
(+ ,(lambda (add-on) +))
(- ,(lambda (add-on) -))
(< ,(lambda (add-on) (sxml:relational-cmp <)))
(> ,(lambda (add-on) (sxml:relational-cmp >)))
(<= ,(lambda (add-on) (sxml:relational-cmp <=)))
(>= ,(lambda (add-on) (sxml:relational-cmp >=)))
(= ,(lambda (add-on) sxml:equal?))
(!= ,(lambda (add-on) sxml:not-equal?))))
(mul-expr ,sxml:arithmetic-eval)
(add-expr ,sxml:arithmetic-eval)
(relational-expr
,(lambda (additive-expr-res-lst cmp-op-lst add-on)
(lambda (nodeset root-node context var-binding)
(let rpt ((res ((car additive-expr-res-lst)
nodeset root-node context var-binding))
(fs (cdr additive-expr-res-lst))
(ops cmp-op-lst))
(if (null? fs)
res
(rpt ((car ops)
res
((car fs) nodeset root-node context var-binding))
(cdr fs)
(cdr ops)))))))
(equality-expr
,(lambda (relational-expr-res-lst cmp-op-lst add-on)
(lambda (nodeset root-node context var-binding)
(let rpt ((res ((car relational-expr-res-lst)
nodeset root-node context var-binding))
(fs (cdr relational-expr-res-lst))
(ops cmp-op-lst))
(if (null? fs)
res
(rpt ((car ops)
res
((car fs) nodeset root-node context var-binding))
(cdr fs)
(cdr ops)))))))
(and-expr
,(lambda (equality-expr-res-lst add-on)
(lambda (nodeset root-node context var-binding)
(let rpt ((fs equality-expr-res-lst))
(cond
((null? fs) #t)
((not (sxml:boolean
((car fs) nodeset root-node context var-binding))) #f)
(else (rpt (cdr fs))))))))
(or-expr
,(lambda (and-expr-res-lst add-on)
(lambda (nodeset root-node context var-binding)
(let rpt ((fs and-expr-res-lst))
(cond
((null? fs) #f)
((sxml:boolean
((car fs) nodeset root-node context var-binding)) #t)
(else (rpt (cdr fs))))))))
(full-xptr
,(lambda (expr-res-lst add-on)
(lambda (nodeset root-node context var-binding)
(let rpt ((fs expr-res-lst))
(if (null? fs)
'()
(let ((nset ((car fs) nodeset root-node context var-binding)))
(if (null? nset)
(rpt (cdr fs))
nset)))))))
(child-seq
((with-name
,(lambda (name-string number-lst add-on)
(let ((funcs
(apply append
(map
(lambda (num)
(list (sxml:child (ntype?? '*)) (node-pos num)))
number-lst))))
(lambda (nodeset root-node context var-binding)
(let ((id-nset ((sxml:child (ntype?? 'id-index))
((sxml:child (ntype?? '@@)) root-node))))
(if
(null? id-nset) '()
(let ((nd (sxml:lookup name-string (cdar id-nset))))
(if (not nd)
'()
(let rpt ((nset (list nd))
(fs funcs))
(if (null? fs)
nset
(rpt ((car fs) nset) (cdr fs))))))))))))
(without-name
,(lambda (number-lst add-on)
(let ((funcs
(apply append
(map
(lambda (num)
(list (sxml:child (ntype?? '*)) (node-pos num)))
number-lst))))
(lambda (nodeset root-node context var-binding)
(if (nodeset? nodeset)
(let rpt ((nodeset nodeset) (res '()))
(if (null? nodeset)
res
(let rpt2 ((nset (list (car nodeset)))
(fs funcs))
(if (null? fs)
(rpt (cdr nodeset) (append res nset))
(rpt2 ((car fs) nset) (cdr fs))))))
(let rpt ((nodeset nodeset) (fs funcs))
(if (null? fs)
nodeset
(rpt ((car fs) nodeset) (cdr fs)))))))))))
))
(define (sxml:api-helper0 parse-proc)
(lambda (xpath-string . ns-binding)
(let ((res (parse-proc
xpath-string
(if (null? ns-binding) ns-binding (car ns-binding))
'())))
(if (txp:error? res) #f
(lambda (node . var-binding)
(let ((node (as-nodeset node)))
(if
(null? var-binding) (res node node (cons 1 1) '())
(let ((var-binding (car var-binding)))
(res
node
(cond ((assq '*root* var-binding)
=> (lambda (pair) (as-nodeset (cdr pair))))
(else node))
(cons 1 1)
var-binding)))))))))
(define sxml:classic-res (txp:parameterize-parser sxml:classic-params))
(define (sxml:api-helper parse-proc)
(lambda (xpath-string . ns-binding)
(let ((res (parse-proc
xpath-string
(if (null? ns-binding) ns-binding (car ns-binding))
'())))
(if (txp:error? res) #f
(lambda (node . var-binding)
(let ((node (as-nodeset node)))
(if
(null? var-binding) (res node node (cons 1 1) '())
(let ((var-binding (car var-binding)))
(res
node
(cond ((assq '*root* var-binding)
=> (lambda (pair) (as-nodeset (cdr pair))))
(else node))
(cons 1 1)
var-binding)))))))))
(define sxml:xpath
(sxml:api-helper (cadr (assq 'xpath sxml:classic-res))))
(define sxml:xpointer
(sxml:api-helper (cadr (assq 'xpointer sxml:classic-res))))
(define sxml:xpath-expr
(sxml:api-helper (cadr (assq 'expr sxml:classic-res))))
(define sxml:xpath+root+vars sxml:xpath)
(define sxml:xpointer+root+vars sxml:xpointer)
(define sxml:xpath+root sxml:xpath)
(define txpath sxml:xpath)
(define (sxml:api-index-helper parse-proc)
(lambda (xpath-string . ns-binding)
(let ((res (parse-proc
xpath-string
(if (null? ns-binding) ns-binding (car ns-binding))
'())))
(if (txp:error? res) #f
(cons
(lambda (node)
(let ((node (as-nodeset node)))
(res node node (cons 1 1) '())))
#t)))))
(define sxml:xpath+index
(sxml:api-index-helper (cadr (assq 'xpath sxml:classic-res))))
(define sxml:xpointer+index
(sxml:api-index-helper (cadr (assq 'xpointer sxml:classic-res))))
(provide (all-defined)))