Transforming

When you only want to change little bits and pieces of an XML document being processed, the SAX proxy comes in handy.

CXML:BROADCAST-HANDLER (sax:abstract-handler) class
CXML:SAX-PROXY (cxml:broadcast-handler) class
 
CXML:MAKE-BROADCAST-HANDLER (&rest handlers) function

Let's look at the BROADCAST-HANDLER first. Like a Common Lisp BROADCAST-STREAM (which sends character to all specified target streams), the BRODACAST-HANDLER delivers SAX events to multiple target handlers at the same time.

And the SAX-PROXY is the special case of a broadcast handler with only one target handler.

Proxies are useful because you can pass events through without having to define any methods, and tweak only those that you care about. Example:

(defclass upcaser (cxml:sax-proxy) ())

(defmethod sax:characters ((handler upcaser) data)
  (call-next-method handler (string-upcase data)))
CL-USER> (cxml:parse "<test>content</test>"
                     (make-instance 'upcaser
                                    :chained-handler (cxml:make-string-sink)))
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<test>CONTENT</test>"