#ifndef SAXWriter_H #define SAXWriter_H #include #include #include namespace SAX { template class basic_Writer : public basic_XMLFilterImpl { public: typedef string_type stringT; typedef typename string_type::value_type charT; typedef typename string_type::traits_type traitsT; typedef std::basic_ostream ostreamT; typedef basic_XMLReader XMLReaderT; typedef basic_XMLFilterImpl XMLFilterT; typedef Unicode UnicodeT; basic_Writer(std::ostream& stream) : indent_(2), stream_(&stream) { } // basic_Writer basic_Writer(ostreamT& stream, XMLReaderT& parent) : XMLFilterT(parent), indent_(2), stream_(&stream) { } // basic_Writer virtual void startDocument(); virtual void endDocument(); virtual void startElement(const stringT& namespaceURI, const stringT& localName, const stringT& qName, const typename XMLFilterT::AttributesT& atts); virtual void endElement(const stringT& namespaceURI, const stringT& localName, const stringT& qName); virtual void characters(const stringT& ch); virtual void processingInstruction(const stringT& target, const stringT& data); virtual void skippedEntity(const stringT& name); private: void doIndent(); bool isDtd(const stringT& name); int indent_; int depth_; ostreamT* stream_; }; // class basic_Writer template void basic_Writer::startDocument() { *stream_ << "" << std::endl; depth_ = 0; XMLFilterT::startDocument(); } // startDocument template void basic_Writer::endDocument() { XMLFilterT::endDocument(); } // endDocument template void basic_Writer::startElement( const stringT& namespaceURI, const stringT& localName, const stringT& qName, const typename XMLFilterT::AttributesT& atts) { doIndent(); *stream_ << UnicodeT::LESS_THAN_SIGN << qName; for(int i = 0; i < atts.getLength(); ++i) *stream_ << UnicodeT::SPACE << atts.getQName(i) << UnicodeT::EQUALS_SIGN << UnicodeT::QUOTATION_MARK << atts.getValue(i) << UnicodeT::QUOTATION_MARK; *stream_ << UnicodeT::GREATER_THAN_SIGN; ++depth_; XMLFilterT::startElement(namespaceURI, localName, qName, atts); } // startElement template void basic_Writer::endElement( const stringT& namespaceURI, const stringT& localName, const stringT& qName) { --depth_; doIndent(); *stream_ << UnicodeT::LESS_THAN_SIGN << UnicodeT::SLASH << qName << UnicodeT::GREATER_THAN_SIGN << UnicodeT::LINE_FEED; XMLFilterT::endElement(namespaceURI, localName, qName); } // endElement template void basic_Writer::characters(const stringT& ch) { *stream_ << ch; XMLFilterT::characters(ch); } // characters template void basic_Writer::processingInstruction(const stringT& target, const stringT& data) { std::cout << UnicodeT::LESS_THAN_SIGN << UnicodeT::QUESTION_MARK << target << UnicodeT::SPACE << data << UnicodeT::QUESTION_MARK << UnicodeT::GREATER_THAN_SIGN; } // processingInstruction template void basic_Writer::skippedEntity(const stringT& name) { if(!isDtd(name)) std::cout << UnicodeT::AMPERSAND << name << UnicodeT::SEMI_COLON; } // skippedEntity template void basic_Writer::doIndent() { for(int i = 0; i < depth_; ++i) *stream_ << UnicodeT::SPACE << UnicodeT::SPACE; } // doIndent template bool basic_Writer::isDtd(const string_type& name) { return (name.length() == 5 && name[0] == UnicodeT::LEFT_SQUARE_BRACKET && name[1] == static_cast('d') && name[2] == static_cast('t') && name[3] == static_cast('d') && name[4] == UnicodeT::RIGHT_SQUARE_BRACKET); } // isDtd typedef basic_Writer Writer; typedef basic_Writer wWriter; } // namespace SAX #endif