#ifndef ARABICA_XSLT_CHOOSE_HANDLER_HPP #define ARABICA_XSLT_CHOOSE_HANDLER_HPP #include "../xslt_choose.hpp" namespace Arabica { namespace XSLT { template class WhenHandler : public ItemContainerHandler > { public: typedef stringT string_type; typedef adaptorT string_adaptor; private: typedef ItemContainerHandler > baseT; typedef StylesheetConstant SC; typedef AttributeValidators AV; public: WhenHandler(Choose* choose, CompilationContext& context) : baseT(context), choose_(choose) { } // WhenHandler virtual When* createContainer(const string_type& /* namespaceURI */, const string_type& /* localName */, const string_type& qName, const SAX::Attributes& atts) { static const AV rules = AV::rule(SC::test, true); string_type test = rules.gather(qName, atts)[SC::test]; return new When(baseT::context().xpath_expression(test)); } // startElement virtual void endElement(const string_type& /* namespaceURI */, const string_type& /* localName */, const string_type& /* qName */) { choose_->add_when(baseT::container()); baseT::context().pop(); } // endElement private: Choose* choose_; }; // class WhenHandler template class OtherwiseHandler : public ItemContainerHandler > { typedef ItemContainerHandler > baseT; typedef StylesheetConstant SC; public: OtherwiseHandler(Choose* choose, CompilationContext& context) : baseT(context), choose_(choose) { } // OtherwiseHandler virtual Otherwise* createContainer(const string_type& /* namespaceURI */, const string_type& /* localName */, const string_type& /* qName */, const SAX::Attributes& atts) { if(atts.getLength()) throw SAX::SAXException("xsl:otherwise may not have any attributes"); return new Otherwise(); } // createContainer virtual void endElement(const string_type& /* namespaceURI */, const string_type& /* localName */, const string_type& /* qName */) { choose_->set_otherwise(baseT::container()); baseT::context().pop(); } // endElement private: Choose* choose_; }; // class OtherwiseHandler template class ChooseHandler : public SAX::DefaultHandler { typedef StylesheetConstant SC; public: ChooseHandler(CompilationContext& context) : context_(context), choose_(0), seenWhere_(false), seenOtherwise_(false) { } // ChooseHandler virtual void startElement(const string_type& namespaceURI, const string_type& localName, const string_type& qName, const SAX::Attributes& atts) { if(!choose_) { if(atts.getLength() != 0) throw SAX::SAXException("xsl:choose can not have attributes"); choose_ = new Choose(); return; } // if ... if(namespaceURI == StylesheetConstant::NamespaceURI) { if(localName == SC::when) { seenWhere_ = true; if(seenOtherwise_) throw SAX::SAXException("xsl:otherwise must be the last element in an xsl:choose"); context_.push(0, new WhenHandler(choose_, context_), namespaceURI, localName, qName, atts); return; } // if(localName == "when") if(localName == SC::otherwise) { if(seenOtherwise_) throw SAX::SAXException("xsl:choose may only have one xsl:otherwise element"); seenOtherwise_ = true; context_.push(0, new OtherwiseHandler(choose_, context_), namespaceURI, localName, qName, atts); return; } // if(localName == "otherwise") } // if ... throw SAX::SAXException("xsl:choose can not contain " + string_adaptor::asStdString(qName) + ". Only xsl:when and xsl:otherwise are allowed"); } // startElement virtual void endElement(const string_type& /* namespaceURI */, const string_type& /* localName */, const string_type& /* qName */) { if(!seenWhere_) throw SAX::SAXException("xsl:choose must contain at least one xsl:where element"); context_.parentContainer().add_item(choose_); context_.pop(); } // endElement virtual void characters(const string_type& ch) { verifyNoCharacterData(ch, SC::choose); } // characters private: CompilationContext& context_; Choose* choose_; bool seenWhere_; bool seenOtherwise_; }; // class ChooseHandler } // namespace XSLT } // namespace Arabica #endif