Re: sxml:sxml->xml
[email protected] Thu, 16 Oct 2003 11:46:27 -0700 (PDT)
| Newsgroups | gmane.lisp.scheme.ssax-sxml |
|---|---|
| Message-ID | <[email protected]> |
Hello!
> You will get:
> > "<*TOP*><Person
> id='1111'><FirstName>Homer</FirstName><LastName>Simpson</LastName><EmptyElem
> entHere/></Person></*TOP*>"
That '*TOP*' shouldn't be there. Perhaps you may want to make a
special condiction in sxml:sxml->xml to eliminate *TOP* and replace
it with an XML declaration. Incidentally, sxml:sxml->xml has another
problem: it doesn't sanitize bad characters in the attributes. I think
I mentioned that to Kirill some time ago.
Actually, using the stylesheet gives more flexibility, and less
error-prone. Here's the code that takes SXML and prints it out. If you
rather had a string, enclose the code within (with-output-to-string).
(define (to-xml sxml)
(SRV:send-reply
(pre-post-order sxml
`((@
((*default* ; local override for attributes
. ,(lambda (attr-key . value)
(if (null? value) (list #\space attr-key "='" attr-key "'")
(list #\space attr-key "='" value #\')))))
. ,(lambda (trigger . value) (cons '@ value)))
(*default* . ,(lambda (tag . elems)
(if (and (pair? elems) (pair? (car elems))
(eq? '@ (caar elems)))
(list #\< tag (cdar elems)
(if (pair? (cdr elems)) (list #\> (cdr elems)
"</" tag #\>)
"/>"))
(cons #\< (cons tag
(if (pair? elems)
(list #\> elems "</" tag #\>) '("/>")))))))
(*text* . ,(let ((string->goodXML
(make-char-quotator
'((#\< . "<") (#\> . ">")
(#\& . "&") (#\" . """)
(#\' . "'")))))
(lambda (trigger str)
(if (string? str) (string->goodXML str) str))))
(*TOP*
. ,(lambda (tag . elems)
(list
"<?xml version=\"1.0\"?>"
;"<!DOCTYPE productlist SYSTEM \"productlist.dtd\">"
elems)))
))))
(to-xml '(*TOP*
(Person
(@ (id "1111"))
(FirstName "Homer")
(LastName "Simpson")
(EmptyElementHere))))
prints the desired XML document. The code uses the bare minimum:
SRV:send-reply, pre-post-order and make-char-quotator, all of which
should be available (and are available in the CVS repository). I ran
the code in Bigloo against the CVS current code.
I must mention that there are many things you may want to do when
converting SXML to XML: e.g., make the XML prettier by inserting
newlines and spaces. That is trickier than it sounds. You can add the
processing of PI, COMMENTs and other stuff. Namespaces offer more
choices and more trouble. You may want to look at sxmlcnv by Kiyoka
Nishiyama
http://www.netfort.gr.jp/~kiyoka/sxmlcnv/
that does several of these advanced things.
Incidentally, it's possible to turn SXML into XML without creating any
intermediate list structure first. This greatly improves the speed and
especially the latency, when dealing with large (order of megabytes)
SXML documents. I've been using this approach in production for some
time. I haven't gotten around to writing it up though.
-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
SourceForge.net hosts over 70,000 Open Source Projects.
See the people who have HELPED US provide better services:
Click here: http://sourceforge.net/supporters.php