unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* Guile & Sablotron
@ 2004-03-09 17:32 Brian S McQueen
  2004-03-12  8:52 ` Thien-Thi Nguyen
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Brian S McQueen @ 2004-03-09 17:32 UTC (permalink / raw)


I have a project in mind, and I would like to discuss it on the list here
before I get started.  I want to put a Guile interface on the Sablotron
library:  http://www.gingerall.com/charlie/ga/xml/p_sab.xml

Sablotron is the library for XSLT processing.  Its the one used int
Apache's Axkit:  http://axkit.org/

In the short term I want to be able to use Sablotron as my template
engine, from my Scheme programs.  In the longterm I want to add this
Guile/Sablotron binding to the Recluse web server:

http://www.pyro.net/~crayc/code/recluse/

In Recluse, the guy (Mr. C. Ray C., who reads this list) has added Guile
to the slim, fast thttp web server. This web server has a scheme config
file, and seamless execution of scheme code for dynamic content
generation.

The addition of Sablotron to the web server will produce a very effective
platform for web development for us Scheme lovers.  I want to produce an
environment for the creativity and productivity of the Scheme community to
prosper, and one in which I enjoy working.  I am continually annoyed with
the Java/Tomcat projects, and I believe they are headed off into the
weeds.  I want to have a similar environment for the Scheme folks.

So the big picture presented here may be interesting to some folks, and
may be worth discussing.  But in particular I want help designing the
correct way to export Sablotron to Guile.  The Sablotron API is very C
oriented.  A more functional style interface needs to be provided for use
in Scheme.  I don't know which way to go there yet.

Who is interested in these projects?

Guile & Sablotron!  Who is interested?  I need to discuss this with
someone!  TTN!  You do a lot of web work.  Using a template engine is the
way to go for handling the presentation of data.  The programs can produce
generic data of this sort:

<sales>

        <division id="North">
                <revenue>10</revenue>
                <growth>9</growth>
                <bonus>7</bonus>
        </division>

        <division id="South">
                <revenue>4</revenue>
                <growth>3</growth>
                <bonus>4</bonus>
        </division>

        <division id="West">
                <revenue>6</revenue>
                <growth>-1.5</growth>
                <bonus>2</bonus>
        </division>

</sales>

That could be the output of a single stored proc in your database.  The
template engine turns that into html via a style sheet (or pdf, or other
formats).

Folks, the Guile project is great!  I really want it to stay alive and
prosper, and this XML/XSLT technology is good stuff.  We need to provide
access to it via Scheme so we can continue to attract new, energetic,
productive developers to the Scheme community.  It will be very good for
the Guile project!

Brian McQueen
NAS Division
NASA/Ames







_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Guile & Sablotron
  2004-03-09 17:32 Guile & Sablotron Brian S McQueen
@ 2004-03-12  8:52 ` Thien-Thi Nguyen
  2004-03-14  9:09 ` XML, HTML and Scheme (was: Guile & Sablotron) Daniel Skarda
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Thien-Thi Nguyen @ 2004-03-12  8:52 UTC (permalink / raw)
  Cc: guile-user

[-- Attachment #1: Type: text/plain, Size: 1193 bytes --]

   From: Brian S McQueen <bqueen@nas.nasa.gov>
   Date: Tue, 9 Mar 2004 09:32:05 -0800 (PST)

   Using a template engine is the way to go for handling the
   presentation of data.

i surmise from skimming the axkit homepage that the axkit concept
of "template" is not only the traditional "fill this named space w/
customized bits", but possibly time-varying as well (results are
not fully finalized; tags are kept around; caching is selective).
that's a fine approach to flattening the tree.  however, i'm less
than enamored w/ the xml representation, despite its merits.

btw, thanks for your good question on "adding to a list".  it
helped spur recent(ish) development of some (www server-utils *)
modules.  you can find a work-in-progress (but working nonetheless)
webserver that uses these modules, attached.  the first file is the
webserver proper.  the second one contains servlets (callbacks for
dynamic content creation).  it is left as an exercise for the
reader to write a servlet that uses (database postgres*) modules to
make queries, retrieve scheme objects, and send them over the wire.
axkit-like caching is likewise a SMOP.

thi


_____________________________________________

[-- Attachment #2: mgrabmue-webserver.scm --]
[-- Type: application/octet-stream, Size: 8820 bytes --]

#! /bin/sh
GUILE=/tmp/a/b/c/bin/guile ; export GUILE
exec ${GUILE-guile} -e "(ttn-do mgrabmue-webserver)" -s $0 "$@"
!#
;;; ID: $Id$
;;; Copyright (C) 2004 Thien-Thi Nguyen
;;; Copyright (C) 2000, 2001 Martin Grabmueller <mgrabmue@cs.tu-berlin.de>
;;; This program is part of ttn-do, released under GNU GPL v2 with ABSOLUTELY
;;; NO WARRANTY.  See http://www.gnu.org/copyleft/gpl.txt for details.
;;;
;;; Description: Simple web server.

;;; Commentary:

;; Usage: mgrabmue-webserver -r DIR [options...]
;;   -p, --port=PORT     -- Listen on PORT (default: 8001)
;;   -r, --docroot=DIR   -- Specify DIR as filesystem root (required)
;;   -u, --ulibdir=DIR   -- Look in DIR for mgrabmue-servlets.scm

;;; Code:

(define-module (ttn-do mgrabmue-webserver)
  #:use-module (scripts PROGRAM)
  #:use-module (scripts slurp)
  #:use-module (ice-9 regex)
  #:use-module (www server-utils big-dishing-loop)
  #:use-module (www server-utils filesystem)
  #:use-module (www server-utils log)
  #:use-module (www data http-status)
  #:use-module (www data content-type))

(define *server-name* "SizzWeb 0.0.3")

(define no-access? #f)                  ; set by main/qop
(define fs-name #f)

\f
;; Standard responses ================================================

(define (add-standard-headers M)
  (M #:add-header #:Date (strftime "%a, %m %b %Y %H:%M:%S GMT"
                                   (gmtime (current-time))))
  (M #:add-header #:Server *server-name*))

(define (*top+title title)
  (list "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">"
        "<HTML><HEAD><TITLE>" title "</TITLE></HEAD><BODY>"))

(define (*bottom)
  (list "<HR><ADDRESS>" *server-name* "</ADDRESS></BODY></HTML>"))

(define (send-error M number . body)
  (let ((msg (assq-ref *http-status* number))
        (nstr (number->string number)))
    (M #:set-reply-status number msg)
    (add-standard-headers M)
    (M #:add-header #:Connection "close")
    (M #:add-header #:Content-Type "text/html")
    (M #:add-content
       (*top+title (list nstr " " msg))
       "<H2>" nstr " " msg "</H2>"
       body
       (*bottom))
    (M #:rechunk-content #t)
    (M #:send-reply)))

(define (send-not-found M upath)
  (send-error M 404
              "The requested URL:<BR><B>"
              upath
              "</B><BR>was not found on this server."))

(define (send-bad-request M)
  (send-error M 400
              "Your browser sent a request that"
              " this server could not understand."))

(define (send-unknown-method M method upath)
  (send-error M 501
              "<B>"
              (symbol->string method)
              "</B> to <B>"
              upath
              "</B> not supported."))

(define (send-forbidden M upath)
  (send-error M 403
              "You do not have permission to access:<BR><B>"
              upath
              "</B>"))

(define (send-moved-permanently M upath)
  (send-error 301
              "The document has been moved <A HREF=\""
              upath
              "\">here</A>"))

\f
;; Special responses =================================================

;; Construct and send a directory index.
;;
(define (send-generated-directory-index M upath dir)
  (add-standard-headers M)
  (M #:set-reply-status:success)
  (M #:add-header #:Connection "close")
  (M #:add-header #:Content-Type "text/html")
  (let ((rev (reverse (string->list upath))))
    (set! upath (list->string (reverse (if (char=? #\/ (car rev))
                                           (cdr rev)
                                           rev)))))
  (M #:add-content
     (*top+title (list "Directory " upath))
     "<H2>Parent Directories</H2>"
     (let loop ((start 0) (acc '()))
       (cond ((string-index upath #\/ start)
              => (lambda (cut)
                   (set! cut (1+ cut))
                   (loop cut (acons start cut acc))))
             (else
              (map (lambda (x)
                     (list "<A HREF=\""
                           (substring upath 0 (cdr x))
                           "\">"
                           (substring upath (car x) (cdr x))
                           "</A><BR>"))
                   (reverse acc)))))
     "<H2>Directory " (basename upath) "</H2><HR><PRE>"
     (sort
      (let ((dir-stream (opendir dir)))
        (let loop ((file (readdir dir-stream)) (acc '()))
          (if (eof-object? file)
              (reverse acc)
              (loop (readdir dir-stream)
                    (if (or (string=? "." file)
                            (string=? ".." file))
                        acc
                        (cons (format #f " <A HREF=~S>~A</A>\n"
                                      (in-vicinity upath file) file)
                              acc))))))
      string<?)
     "</PRE>"
     (*bottom))
  (M #:rechunk-content (* 16 1024))
  (M #:send-reply))

;; Transfer a file.
;;
(define (transmit-file M filename)
  (add-standard-headers M)
  (M #:set-reply-status:success)
  (M #:add-header #:Connection "close")
  (M #:add-header #:Content-Type (filename->content-type filename "text/plain"))
  (M #:add-content (slurp filename))
  (M #:rechunk-content (* 16 1024))
  (M #:send-reply))

\f
;; Dynamic URLs ======================================================

;; This is the list of registered dynamic handlers.  The car of the
;; association is a compiled regexp, the cdr the corresponding handler.

(define *dynamic-url-handlers* '())

(define (add-dynamic-handler! re-str handler)
  (set! *dynamic-url-handlers*
        (append!                        ; maintain order
         *dynamic-url-handlers*
         (acons (make-regexp re-str) handler '()))))

;; Return a dynamic handler suitable for `upath', or #f if non found.
;;
(define (find-dynamic-url-handler upath)
  (let loop ((ls *dynamic-url-handlers*))
    (cond ((null? ls) #f)
          ((regexp-exec (car (car ls)) upath) (cdr (car ls)))
          (else (loop (cdr ls))))))

\f
;; Main program ======================================================

(define (make-server-loop no-access?)
  (make-big-dishing-loop
   #:need-headers #t
   #:need-input-port #t
   #:GET-upath (lambda (M upath headers in-port)
                 (M #:reset-protocol!)
                 (cond ((find-dynamic-url-handler upath)
                        => (lambda (handle)
                             (handle M in-port upath headers)))
                       (else
                        (let ((filename (fs-name upath)))
                          (cond ((not filename)
                                 (send-not-found M upath))
                                ((no-access? filename)
                                 (send-forbidden M upath))
                                ((file-is-directory? filename)
                                 (send-generated-directory-index
                                  M upath filename))
                                (else
                                 (transmit-file M filename))))
                        #t)))
   #:status-box-size 2
   #:bad-request-handler send-bad-request
   #:unknown-http-method-handler send-unknown-method
   #:log (log-http-response-proc (current-output-port))))

(define (main/qop qop)
  (let ((docroot (qop 'docroot (lambda (dir) (in-vicinity dir ""))))
        (listening-port (or (qop 'port string->number)
                            8001)))
    (set! fs-name (upath->filename-proc
                   docroot '("index.shtml" "index.html")))
    (qop 'ulibdir (lambda (dir)
                    (false-if-exception
                     (load (in-vicinity dir "mgrabmue-servlets.scm")))))
    (format #t "Starting on port ~A, with docroot ~S.\n"
            listening-port docroot)
    ((make-server-loop (access-forbidden?-proc
                        docroot (regexp-quote "/../")))
     listening-port)
    (format #t "Shutting down\n")
    #t))

(define (main args)
  (HVQC-MAIN args main/qop
             '(usage . commentary)
             '(version . "1.0")
             (let ((valid-dir (lambda (file)
                                (define (bad msg)
                                  (format #t "~A: ~A: ~A\n"
                                          (car args) msg file)
                                  #f)
                                (and (or (access? file R_OK)
                                         (bad "cannot read"))
                                     (or (file-is-directory? file)
                                         (bad "not a directory"))))))
               `(option-spec
                 (port    (single-char #\p) (value #t))
                 (docroot (single-char #\r) (value #t) (required? #t)
                          (predicate ,valid-dir))
                 (ulibdir (single-char #\u) (value #t)
                          (predicate ,valid-dir))))))

;;; mgrabmue-webserver.scm ends here

[-- Attachment #3: mgrabmue-servlets.scm --]
[-- Type: application/octet-stream, Size: 5503 bytes --]

;;; mgrabmue-servlets.scm -- user servlets for the webserver
;;;
;;; Copyright (C) 2004 Thien-Thi Nguyen
;;; Copyright (C) 2000, 2001 Martin Grabmueller <mgrabmue@cs.tu-berlin.de>
;;;
;;; This is free software; you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 2, or (at your option)
;;; any later version.
;;;
;;; This software is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with this package; see the file COPYING.  If not, write to
;;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;;; Boston, MA 02111-1307, USA.

;;; Commentary:

;; This file demonstrates how you can write your own customized servlet
;; in SizzWeb.  A servlet procedure must perform the followin steps:
;; - Set the HTTP response status
;; - Add appropriate headers
;; - Add content
;; - Commit the response.

;;; Code:

(define-module (ttn-do mgrabmue-webserver)
  #:use-module (ttn shell-command-to-string))

;; Kill the server loop (by returning #f).
;;
(add-dynamic-handler!
 "^/qqq"
 (lambda (M in-port upath headers)
   (add-standard-headers M)
   (M #:set-reply-status:success)
   (M #:add-header #:Connection "close")
   (M #:add-header #:Content-Type "text/plain")
   (M #:add-content "bye!")
   (M #:send-reply)
   #f))

;; Write a short message and dump the headers from the client.
;;
(add-dynamic-handler!
 "^/test"
 (lambda (M in-port upath headers)
   (add-standard-headers M)
   (M #:set-reply-status:success)
   (M #:add-header #:Connection "close")
   (M #:add-header #:Content-Type "text/html")
   (M #:add-content
      "<HTML><HEAD><TITLE>It worked</TITLE></HEAD><BODY>"
      "<P>It seems that dynamic URL support in " *server-name* " works.</P>"
      "<P>The following headers were sent by your browser:</P><TABLE>"
      (map (lambda (x)
             (list "<TR><TD>" (car x) "</TD><TD>" (cdr x) "</TD></TR>\n"))
           headers)
      "</TABLE></BODY></HTML>")
   (M #:send-reply)))

;; Register the time servlet to respond for all URLs below `/time'.
;;
(add-dynamic-handler!
 "/time"
 (lambda (M in-port upath headers)
   (add-standard-headers M)
   (M #:set-reply-status:success)
   (M #:add-header #:Connection "close")
   (M #:add-header #:Content-Type "text/html")
   (M #:add-content
      "<HTML><HEAD><TITLE>Time servlet</TITLE></HEAD>"
      "<BODY><H2>Time servlet</H2>"
      "<P>Current local time on this server: "
      (strftime "%H:%M" (localtime (current-time)))
      "</P></BODY></HTML>")
   (M #:send-reply)))

;; Register the user servlet to respond for all URLs below `/user'.
;;
(add-dynamic-handler!
 "/user"
 (lambda (M in-port upath headers)
   (add-standard-headers M)
   (M #:set-reply-status:success)
   (M #:add-header #:Connection "close")
   (M #:add-header #:Content-Type "text/html")
   (M #:add-content
      "<HTML><HEAD><TITLE>User servlet</TITLE></HEAD>"
      "<BODY><H2>User servlet</H2>"
      "<P>This is the servlet from the Sizzle distribution talking.</P>"
      "<P>You requested <TT>" upath "</TT>.</P></BODY></HTML>")
   (M #:send-reply)))

;; A dynamic upath handler for .shtml files.  File contents are scanned
;; for `<!--#SSIKEY VAR=VAL-->' comments, which are replaced w/ the
;; appropriate "server-side include" output.  At this time, only
;; `#include' and `#exec' are handled.  Fully expanded:
;;
;;    <!--#include filename="FILENAME"-->
;;    <!--#exec cmd="PROGRAM [ARGS ...]"-->
;;
;; Note that the double-quotes are required.  [This may differ somewhat
;; from Apache behavior -- sorry, manual not handy at the moment, this
;; is from memory.  We should probably fix this to make it mimic Apache
;; as much as possible to avoid user confusion.  -ttn]
;;
(add-dynamic-handler!
 "\\.shtml$"
 (lambda (M in-port upath headers)
   (add-standard-headers M)
   (M #:set-reply-status:success)
   (M #:add-header #:Connection "close")
   (M #:add-header #:Content-Type "text/html")
   (let* ((rx (make-regexp "<!--#([a-z]+) ([a-z]+)=\"([^>]+)\"-->"))
          (ssi (fs-name upath))
          (str (slurp ssi))
          (max (string-length str))
          (c '()))
     ;; do two passes to allow for validation (tbd)
     (let loop ((start 0) (acc '()))
       (if (>= start max)
           (set! c (reverse acc))
           (let ((m (regexp-exec rx str start)))
             (if m
                 (loop (match:end m)
                       (cons (cons (string->symbol (match:substring m 1))
                                   (match:substring m 3))
                             (cons (substring str start (match:start m))
                                   acc)))
                 (loop max (cons (substring str start max) acc))))))
     (chdir (dirname ssi))
     (for-each (lambda (chunk)
                 (M #:add-content
                    (if (string? chunk)
                        chunk
                        (case (car chunk)
                          ((include)
                           (slurp (cdr chunk)))
                          ((exec)
                           (shell-command-to-string (cdr chunk)))
                          (else "(???)")))))
               c))
   (M #:send-reply)))

;;; mgrabmue-servlets.scm ends here

[-- Attachment #4: Type: text/plain, Size: 139 bytes --]

_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user

^ permalink raw reply	[flat|nested] 6+ messages in thread

* XML, HTML and Scheme (was: Guile & Sablotron)
  2004-03-09 17:32 Guile & Sablotron Brian S McQueen
  2004-03-12  8:52 ` Thien-Thi Nguyen
@ 2004-03-14  9:09 ` Daniel Skarda
  2004-03-15 16:36 ` Guile & Sablotron Mike Gran
  2004-03-18  0:02 ` Christopher Cramer
  3 siblings, 0 replies; 6+ messages in thread
From: Daniel Skarda @ 2004-03-14  9:09 UTC (permalink / raw)
  Cc: guile-user

Hello Brian,

  before you start work on writing xml/html/... from Scheme, you should answer
yourself some questions:

  1) What is XML/HTML as a data structure?

  2) What is the most natural (and simple) way to represent it in Scheme?
 
  3) What would you use to describe transformations on such representation?

  4) What is the most natural way to represent a "template"?

  5) How you can mix code and html/xml data (templates) in the most easy way?

  6) Do you really need XSLT? ;-)

  I wish you good luck in finding your answers to above questions :)

0.

Hint: What does the name "Lisp" mean?



_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Guile & Sablotron
  2004-03-09 17:32 Guile & Sablotron Brian S McQueen
  2004-03-12  8:52 ` Thien-Thi Nguyen
  2004-03-14  9:09 ` XML, HTML and Scheme (was: Guile & Sablotron) Daniel Skarda
@ 2004-03-15 16:36 ` Mike Gran
  2004-03-18  0:02 ` Christopher Cramer
  3 siblings, 0 replies; 6+ messages in thread
From: Mike Gran @ 2004-03-15 16:36 UTC (permalink / raw)


--- Brian S McQueen <bqueen@nas.nasa.gov> wrote:
> I want to put a Guile interface on the Sablotron
> library:  http://www.gingerall.com/charlie/ga/xml/p_sab.xml

> In the short term I want to be able to use Sablotron as my template
> engine, from my Scheme programs.  In the longterm I want to add this
> Guile/Sablotron binding to the Recluse web server:

Actually, it might be more efficient to do the binding for the XSLT lib
and the webserver binding at the same time.  That way, you'd only have
to wrap the API relevant to CGI processing, which wouldn't take much
time at all.

You mentioned Recluse as a server.  As ttn pointed out, there is an all
guile httpd solution (from guile-www).  Also, there is a good,
Guile-friendly webserver named Serveez.  I wonder how their performance
compares?

-Mike Gran

__________________________________
Do you Yahoo!?
Yahoo! Mail - More reliable, more storage, less spam
http://mail.yahoo.com


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Guile & Sablotron
  2004-03-09 17:32 Guile & Sablotron Brian S McQueen
                   ` (2 preceding siblings ...)
  2004-03-15 16:36 ` Guile & Sablotron Mike Gran
@ 2004-03-18  0:02 ` Christopher Cramer
  2004-04-20 17:59   ` Kirill Lisovsky
  3 siblings, 1 reply; 6+ messages in thread
From: Christopher Cramer @ 2004-03-18  0:02 UTC (permalink / raw)


On Tue, Mar 09, 2004 at 09:32:05AM -0800, Brian S McQueen wrote:
> Guile & Sablotron!  Who is interested?  I need to discuss this with
> someone!  TTN!  You do a lot of web work.  Using a template engine is the
> way to go for handling the presentation of data.  The programs can produce
> generic data of this sort:
> 
> <sales>
> 
>         <division id="North">
>                 <revenue>10</revenue>
>                 <growth>9</growth>
>                 <bonus>7</bonus>
>         </division>
> 
>         <division id="South">
>                 <revenue>4</revenue>
>                 <growth>3</growth>
>                 <bonus>4</bonus>
>         </division>
> 
>         <division id="West">
>                 <revenue>6</revenue>
>                 <growth>-1.5</growth>
>                 <bonus>2</bonus>
>         </division>
> 
> </sales>

I'm pretty much sold on the idea of integrating templates into Recluse.
But that sort of output seems a little less elegant than I would like.
You'd end up with display or format calls outputting XML, which is an
improvement over outputting HTML, but I wonder if instead of outputting
XML we could just return a list.

Something like:

'(sales
	(division (id "North")
		(revenue 10)
		(growth 9)
		(bonus 7))

	(division (id "South")
		(revenue 4)
		(growth 3)
		(bonus 4)))

I think being able to write the whole thing using just sql->list, map,
append, etc. (or even backquotes) would make it a lot easier.

I suppose there might be interoperability benefits to using XML though.
Maybe we should have some ->xml and xml-> procedures.

-- 
Christopher Cramer <crayc@pyro.net> <http://www.pyro.net/~crayc/>
In politics you have to understand not where the voters are when a poll
is taken, but where they are likely to end up on Election Day.
-- Rep. Tom Davis, former NRCC Chairman


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Guile & Sablotron
  2004-03-18  0:02 ` Christopher Cramer
@ 2004-04-20 17:59   ` Kirill Lisovsky
  0 siblings, 0 replies; 6+ messages in thread
From: Kirill Lisovsky @ 2004-04-20 17:59 UTC (permalink / raw)
  Cc: guile-user

Hello,

Please drop a look at SXML:
http://okmij.org/ftp/Scheme/SXML.html

It represents

> >         <division id="North">
> >                 <revenue>10</revenue>
> >                 <growth>9</growth>
> >                 <bonus>7</bonus>
> >         </division>

...

> 	(division (id "North")
> 		(revenue 10)
> 		(growth 9)
> 		(bonus 7))


as

(division (@ (id "North"))
	  (revenue 10)
	  (growth 9)
	  (bonus 7))

which makes it clear that "id" is attribute, and not a nested element.
It also provides support for Namespaces, SXPath and XPath,
xml->sxml parsing, sxml->xml/html transformation, and much more...

More information may be found at:
http://ssax.sourceforge.net
http://okmij.org/ftp/Scheme/xml.html
http://pair.com/lisovsky/xml/
http://celtic.benderweb.net/webit/

Maillist:
http://lists.sourceforge.net/lists/listinfo/ssax-sxml

A Guile-oriented tutorial may be found at:
http://www-106.ibm.com/developerworks/library/x-matters31.html

Best regards,
         Kirill.


On Wed, 17 Mar 2004, Christopher Cramer wrote:

> On Tue, Mar 09, 2004 at 09:32:05AM -0800, Brian S McQueen wrote:
> > Guile & Sablotron!  Who is interested?  I need to discuss this with
> > someone!  TTN!  You do a lot of web work.  Using a template engine is the
> > way to go for handling the presentation of data.  The programs can produce
> > generic data of this sort:
> >
> > <sales>
> >
> >         <division id="North">
> >                 <revenue>10</revenue>
> >                 <growth>9</growth>
> >                 <bonus>7</bonus>
> >         </division>
> >
> >         <division id="South">
> >                 <revenue>4</revenue>
> >                 <growth>3</growth>
> >                 <bonus>4</bonus>
> >         </division>
> >
> >         <division id="West">
> >                 <revenue>6</revenue>
> >                 <growth>-1.5</growth>
> >                 <bonus>2</bonus>
> >         </division>
> >
> > </sales>
>
> I'm pretty much sold on the idea of integrating templates into Recluse.
> But that sort of output seems a little less elegant than I would like.
> You'd end up with display or format calls outputting XML, which is an
> improvement over outputting HTML, but I wonder if instead of outputting
> XML we could just return a list.
>
> Something like:
>
> '(sales
> 	(division (id "North")
> 		(revenue 10)
> 		(growth 9)
> 		(bonus 7))
>
> 	(division (id "South")
> 		(revenue 4)
> 		(growth 3)
> 		(bonus 4)))
>
> I think being able to write the whole thing using just sql->list, map,
> append, etc. (or even backquotes) would make it a lot easier.
>
> I suppose there might be interoperability benefits to using XML though.
> Maybe we should have some ->xml and xml-> procedures.
>
> --
> Christopher Cramer <crayc@pyro.net> <http://www.pyro.net/~crayc/>
> In politics you have to understand not where the voters are when a poll
> is taken, but where they are likely to end up on Election Day.
> -- Rep. Tom Davis, former NRCC Chairman
>
>
> _______________________________________________
> Guile-user mailing list
> Guile-user@gnu.org
> http://mail.gnu.org/mailman/listinfo/guile-user
>


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2004-04-20 17:59 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-03-09 17:32 Guile & Sablotron Brian S McQueen
2004-03-12  8:52 ` Thien-Thi Nguyen
2004-03-14  9:09 ` XML, HTML and Scheme (was: Guile & Sablotron) Daniel Skarda
2004-03-15 16:36 ` Guile & Sablotron Mike Gran
2004-03-18  0:02 ` Christopher Cramer
2004-04-20 17:59   ` Kirill Lisovsky

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).