One more technical bit: There are events surrounding the beginning and end of the entire document.

SAX:START-DOCUMENT (handler) generic function
SAX:END-DOCUMENT (handler) generic function

The end-document event is particularly useful, because it is the only method whose return value callers care about. Anything you return from that method gets passed through to cxml:parse.

With this knowledge, we can rewrite the "tostring" example without the help of the special variable:

(defclass tostring2 (sax:default-handler)
  ((acc :initform (make-string-output-stream) :accessor acc)))

(defmethod sax:characters ((handler tostring2) data)
  (write-string data (acc handler)))

(defmethod sax:end-document ((handler tostring2))
  (get-output-stream-string (acc handler)))
CL-USER> (cxml:parse "<x>foo<y>bar</y>baz</x>" (make-instance 'tostring2))