The following, which owes much to James Clark's example in transform.htm from the Jade documentation and to Dan Speck's DSSSList post of October 10, 1997, performs a rudimentary SGML–SGML identity transformation. It does not regenerate the DOCTYPE declaration, nor does it handle processing instructions.
<!doctype style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN">
(declare-flow-object-class element
"UNREGISTERED::James Clark//Flow Object Class::element")
(declare-flow-object-class empty-element
"UNREGISTERED::James Clark//Flow Object Class::empty-element")
(declare-characteristic preserve-sdata?
"UNREGISTERED::James Clark//Characteristic::preserve-sdata?"
#t)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Default rule
(default (output-element))
(define (output-element #!optional (node (current-node)))
(if (node-property "must-omit-end-tag?" node)
(make empty-element
attributes: (copy-attributes))
(make element
attributes: (copy-attributes))))
(define (copy-attributes #!optional (nd (current-node)))
(let loop ((atts (named-node-list-names (attributes nd))))
(if (null? atts)
'()
(let* ((name (car atts))
(value (attribute-string name nd)))
(if value
(cons (list name value)
(loop (cdr atts)))
(loop (cdr atts)))))))