#ifndef ARABICA_XSLT_FOR_EACH_HANDLER_HPP #define ARABICA_XSLT_FOR_EACH_HANDLER_HPP #include "../xslt_for_each.hpp" #include "xslt_item_container_handler.hpp" #include "xslt_sort_handler.hpp" namespace Arabica { namespace XSLT { template class ForEachHandler : public ItemContainerHandler > { typedef StylesheetConstant SC; typedef ItemContainerHandler > baseT; public: ForEachHandler(CompilationContext& context) : baseT(context), done_sort_(false) { } // ForEachHandler protected: virtual ForEach* createContainer(const string_type& /* namespaceURI */, const string_type& /* localName */, const string_type& qName, const SAX::Attributes& atts) { static const ValueRule rules[] = { { SC::select, true, 0, 0 }, { string_adaptor::empty_string(), false, 0, 0 } }; string_type select = gatherAttributes(qName, atts, rules)[SC::select]; return new ForEach(baseT::context().xpath_expression(select)); } // createContainer virtual bool createChild(const string_type& namespaceURI, const string_type& localName, const string_type& qName, const SAX::Attributes& atts) { if((namespaceURI == StylesheetConstant::NamespaceURI) && (localName == SC::sort)) { if(!done_sort_) { baseT::context().push(0, new SortHandler(baseT::context(), *baseT::container()), namespaceURI, localName, qName, atts); return true; } else throw SAX::SAXException("xsl:sort must immediately follow xsl:for-each"); } // if ... done_sort_ = true; return baseT::createChild(namespaceURI, localName, qName, atts); } // createChild private: bool done_sort_; }; // class ForEachHandler } // namespace XSLT } // namespace Arabica #endif