; Module header is generated automatically #cs(module stx-engine mzscheme (require mzlib/defmacro) (require (rename mzlib/pretty pp pretty-print)) (require (lib "string.ss" "srfi/13")) (require "sxml-tools.ss") (require "sxpathlib.ss") (require "sxpath-ext.ss") (require "txpath.ss") (require "sxpath.ss") (require "libmisc.ss") (require (lib "ssax.ss" "web-server/tests/tmp/ssax")) ;; $Id: stx-engine.scm,v 1.9403 2002/12/25 19:33:48 kl Exp kl $ ; DL: if you are not using "access-remote.scm", uncomment the following line ;(define open-input-resource open-input-file) ;============================================================================= ; Auxilliary (define stx:version (string-append " $Revision: 1.9403 $" nl " $Date: 2002/12/25 19:33:48 $")) (define (stx:error . messages) (cerr nl "STX: ") (apply cerr messages) (cerr nl) (exit -1)) ; Reads content of a given SXML element 'obj' using Scheme reader. ; The content has to be a list of strings (first of them will be read). ; If the content is empty, "" is returned. (define (stx:read-content obj objname) (let ((ct (sxml:content obj))) (cond ((null? ct) "") ((string? (car ct)) (with-exception-handler (lambda(mes) (apply stx:error `("Error " ,nl ,mes ,nl "reading " ,objname " code:" ,nl ,(car ct) ,nl "from element" ,nl ,@(sxml:clean-feed (sxml:sxml->xml obj)) ,nl)) (exit)) (lambda() (call-with-input-string (car ct) read)))) (else (stx:error "Invalid " objname " element:" nl obj))) )) (define (stx:clean-feed . fragments) (reverse (let loop ((fragments fragments) (result '())) (cond ((null? fragments) result) ((not (car fragments)) (loop (cdr fragments) result)) ((null? (car fragments)) (loop (cdr fragments) result)) (else (loop (cdr fragments) (cons (car fragments) result))))))) ; DL: Borrowed from the older version of SXML Tools ; Filter the 'fragments' ; The fragments are a list of strings, characters, ; numbers, thunks, #f -- and other fragments. ; The function traverses the tree depth-first, and returns a list ; of strings, characters and executed thunks, and ignores #f and '(). ; ; If all the meaningful fragments are strings, then ; (apply string-append ... ) ; to a result of this function will return its string-value ; ; It may be considered as a variant of Oleg Kiselyov's SRV:send-reply: ; While SRV:send-reply displays fragments, this function returns the list ; of meaningful fragments and filter out the garbage. (define (sxml:clean-feed . fragments) (reverse (let loop ((fragments fragments) (result '())) (cond ((null? fragments) result) ((not (car fragments)) (loop (cdr fragments) result)) ((null? (car fragments)) (loop (cdr fragments) result)) ((pair? (car fragments)) (loop (cdr fragments) (loop (car fragments) result))) ; ((procedure? (car fragments)) ; (loop (cdr fragments) ; (cons ((car fragments)) ; result))) (else (loop (cdr fragments) (cons (car fragments) result))))))) ;----------------------------------------------------------------------------- ; This functions will be probably moved to sxml-tools ; Transforms top-level *NAMESPACES* in SXML document ; parsed using SSAX 4.9 to aux-list representation compatible to ; SXML-spec. ver. 2.5 (define (sxml:refactor-ns tree) (if (and (pair? tree) (pair? (cdr tree)) (pair? (cadr tree)) (eq? '*NAMESPACES* (caadr tree))) `(,(car tree) (@@ (*NAMESPACES* ,@(cdadr tree))) ,@(cddr tree)) tree)) ; Reads XML document as SXML tree. NS prefixes declared in XML document ; are used as namespace-id's. (define (sxml:xml->sxml-autoprefix name) (sxml:refactor-ns ; workaround for SSAX 4.9 (let ((ns-list (sxml:extract-prefix-assigs name))) (ssax:xml->sxml (open-input-resource name) ns-list)))) ; Extracts a value of attribute with given name from attr-list ;(define (sxml:attr-from-list attr-list name) ; (cond ; ((assq name attr-list) ; => cadr) ; (else #f))) ; Reads a root element of given XML file and returns a list ; of NS-prefix/URIs declared as a list of pairs. (define (sxml:extract-prefix-assigs file) (call-with-input-file file (lambda (p) (ssax:skip-S p) (let loop ((lst (ssax:read-markup-token p))) (case (car lst) ((PI) ; Processing instruction (ssax:skip-pi p) ; ignore until the end (ssax:skip-S p) (loop (ssax:read-markup-token p))) ((START) (filter-and-map (lambda(x) (and (pair? (car x)) (eq? 'xmlns (caar x)))) (lambda(x) (cons (cdar x) (cdr x))) (ssax:read-attributes p '()))) (else (display "Unknown token type: ") (display (car lst)) (exit))))))) ;============================================================================= ; Tree transformation ; stx:apply-templates:: x x x -> ; where ; ::=