#ifndef ARABICA_XSLT_VARIABLES_HANDLER_HPP #define ARABICA_XSLT_VARIABLES_HANDLER_HPP #include "../xslt_param.hpp" #include "../xslt_variable.hpp" #include "xslt_item_container_handler.hpp" namespace Arabica { namespace XSLT { template class VariableHandler : public ItemContainerHandler { public: typedef typename VType::string_type string_type; typedef typename VType::string_adaptor string_adaptor; private: typedef StylesheetConstant SC; typedef AttributeValidators AV; typedef ItemContainerHandler baseT; public: VariableHandler(CompilationContext& context) : baseT(context), has_select_(false), precedence_(Precedence::FrozenPrecedence()) { } // VariableHandler VariableHandler(CompilationContext& context, const Precedence& precedence) : baseT(context), has_select_(false), precedence_(precedence) { } // VariableHandler protected: virtual VType* createContainer(const string_type& /* namespaceURI */, const string_type& /* localName */, const string_type& qName, const SAX::Attributes& atts) { static const AV rules = AV::rule(SC::name, true) .rule(SC::select, false); std::map attrs = rules.gather(qName, atts); const string_type& select = atts.getValue(SC::select); Arabica::XPath::XPathExpressionPtr xpath; if(select != string_adaptor::empty_string()) { xpath = baseT::context().xpath_expression(select); has_select_ = true; } // if ... string_type name = baseT::context().processInternalQName(attrs[SC::name]).clarkName(); return new VType(name, xpath, precedence_); } // createContainer virtual void characters(const string_type& ch) { if(has_select_) { for(typename string_adaptor::const_iterator i = string_adaptor::begin(ch), e = string_adaptor::end(ch); i != e; ++i) if(!Arabica::XML::is_space(*i)) throw SAX::SAXException("A variable or param can not have both a select attribute and text context"); } ItemContainerHandler::characters(ch); } // characters private: bool has_select_; const Precedence precedence_; }; // class VariableHandler template class TopLevelVariableHandler : public VariableHandler { public: typedef typename VType::string_type string_type; typedef typename VType::string_adaptor string_adaptor; typedef VariableHandler baseT; TopLevelVariableHandler(CompilationContext& context) : baseT(context, context.precedence()) { } // VariableHandler virtual void endElement(const string_type& /* namespaceURI */, const string_type& /* localName */, const string_type& /* qName */) { baseT::context().stylesheet().add_variable(baseT::container()); baseT::context().pop(); } // endElement }; // class TopLevelVariableHandler } // namespace XSLT } // namespace Arabica #endif