/* Copyright (c) 2003, WebThing Ltd Author: Nick Kew This program 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 of the License, or (at your option) any later version. This program 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 program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef XERCESHANDLERS #define XERCESHANDLERS //XERCES_CPP_NAMESPACE_USE #include "XercesWriter.h" #include #include #include #include class XercesHandlers : public ContentHandler , public ErrorHandler, public LexicalHandler { public: XercesHandlers( XercesWriter& w, const bool yn) : out(w), depth(0), status(V_OK), suppress(!yn), errorcount(0) { } virtual ~XercesHandlers() { } private: XercesWriter& out ; #ifdef ELEMENTSTACK class ElementStack { const char* element ; class ElementStack* parent ; public: ElementStack(const XMLCh* elt =0, ElementStack* stack =0) : element(XMLString::transcode(elt)) , parent(stack) {} ~ElementStack() {} ElementStack* push(const XMLCh* elt) { return new ElementStack(elt, this) ; } ElementStack* pop() { ElementStack* tmp = parent ; delete element ; delete this ; return tmp ; } const char* peek() const { return element ; } } ; ElementStack* stack ; #else unsigned int depth ; #endif public: virtual void endElement(const XMLCh* const uri, const XMLCh* const name, const XMLCh* const qname) { #ifdef ELEMENTSTACK const char* qn = XMLString::transcode(qname) ; while ( ! XMLString::equals(stack->peek() , qn) ) { out.puts("\n") ; stack = stack->pop() ; } delete qn ; out.puts("\n") ; stack = stack->pop() ; #else out.puts("") ; --depth ; #endif } virtual void startElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname, const Attributes& attrs) { /* out.puts("\n") ; */ out.puts("") ; for (size_t n=0; n < attrs.getLength(); ++n) { out.puts("\t") .escape(attrs.getValue(n)).puts("\n") ; } #ifdef ELEMENTSTACK stack = stack->push(qname) ; #else ++depth ; #endif } virtual void characters(const XMLCh* chars, const unsigned int length) { out.escape(chars, length) ; } virtual void ignorableWhitespace(const XMLCh* const chars, const unsigned int length) { } virtual void endDocument() { #ifdef ELEMENTSTACK #else while ( depth-- ) { out.puts("") ; } #endif // out.puts("\n") ; } virtual void processingInstruction(const XMLCh* const target, const XMLCh* const data) { //out.puts("") // .escape(data).puts("\n") ; } virtual void startDocument() { // out.puts("\n") ; } virtual void setDocumentLocator(const Locator* const locator) { } virtual void startPrefixMapping(const XMLCh* const prefix, const XMLCh* const uri) { } virtual void endPrefixMapping(const XMLCh* const prefix) { } virtual void skippedEntity(const XMLCh* const name) { } #if 0 class XercesDTDHandler : public DTDHandler { private: XercesWriter& out ; public: XercesDTDHandler( XercesWriter& w) : out(w) { } virtual ~XercesDTDHandler() { } virtual void notationDecl (const XMLCh *const name, const XMLCh *const publicId, const XMLCh *const systemId) { } virtual void unparsedEntityDecl (const XMLCh *const name, const XMLCh *const publicId, const XMLCh *const systemId, const XMLCh *const notationName) { } virtual void resetDocType () { } } ; #endif #if 0 class XercesDeclHandler : public DeclHandler { private: XercesWriter& out ; public: XercesDeclHandler( XercesWriter& w) : out(w) { } virtual ~XercesDeclHandler() { } virtual void elementDecl (const XMLCh *const name, const XMLCh *const model) { } virtual void attributeDecl (const XMLCh *const eName, const XMLCh *const aName, const XMLCh *const type, const XMLCh *const mode, const XMLCh *const value) { } virtual void internalEntityDecl (const XMLCh *const name, const XMLCh *const value) { } virtual void externalEntityDecl (const XMLCh *const name, const XMLCh *const publicId, const XMLCh *const systemId) { } } ; #endif private: typedef enum { V_OK=0, V_WARNING=1, V_ERROR=2, V_FATAL=3 } ValStatus ; ValStatus status ; const bool suppress ; size_t errorcount ; void setstatus(const ValStatus stat) { if ( status < stat ) status = stat ; } void message(const char* severity, const SAXParseException& ex) { if ( suppress ) return ; // char* sysid = XMLString::transcode(ex.getSystemId()) ; // char* msg = XMLString::transcode(ex.getMessage()) ; out.puts("") .escape(ex.getMessage()).puts("\n") ; // delete msg ; // delete sysid ; } public: virtual void error(const SAXParseException& exception) { ++errorcount ; setstatus(V_ERROR) ; message("error", exception) ; } virtual void warning(const SAXParseException& exception) { setstatus(V_WARNING) ; message("warning", exception) ; } virtual void fatalError(const SAXParseException& exception) { ++errorcount ; setstatus(V_FATAL) ; message("fatal", exception) ; } virtual void resetErrors() { status = V_OK ; errorcount = 0 ; } void report() { out.puts("") ; switch ( status ) { case V_OK: case V_WARNING: out.puts("pass") ; break ; case V_ERROR: case V_FATAL: out.puts("fail") ; break ; default: out.puts("BUG!") ; break ; } out.puts("") ; resetErrors() ; } virtual void startDTD(const XMLCh* const name, const XMLCh* const publicId, const XMLCh* const systemId) { out.puts("\n") ; } virtual void endDTD() { resetErrors() ; out.puts("\n") ; } virtual void endCDATA() { out.puts("\n") ; } virtual void startCDATA() { out.puts("") ; } virtual void startEntity(const XMLCh* const name) { } virtual void endEntity(const XMLCh* const name) { } virtual void comment(const XMLCh *const chars, const unsigned int length) { } } ; #endif