#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: WhenHandler(Choose* choose, CompilationContext& context) : ItemContainerHandler >(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 ValueRule rules[] = { { "test", true, 0, 0 }, { 0, false, 0, 0 } }; string_type test = gatherAttributes(qName, atts, rules)["test"]; return new When(ItemContainerHandler >::context().xpath_expression(test)); } // startElement virtual void endElement(const string_type& /* namespaceURI */, const string_type& /* localName */, const string_type& /* qName */) { choose_->add_when(ItemContainerHandler >::container()); context().pop(); } // endElement private: Choose* choose_; }; // class WhenHandler template class OtherwiseHandler : public ItemContainerHandler > { public: OtherwiseHandler(Choose* choose, CompilationContext& context) : ItemContainerHandler >(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(container()); context().pop(); } // endElement private: Choose* choose_; }; // class OtherwiseHandler template class ChooseHandler : public SAX::DefaultHandler { 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 == "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 == "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 " + 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, "xsl:choose"); } // characters private: CompilationContext& context_; Choose* choose_; bool seenWhere_; bool seenOtherwise_; }; // class ChooseHandler } // namespace XSLT } // namespace Arabica #endif