diff --git a/include/XSLT/impl/handler/xslt_include_handler.hpp b/include/XSLT/impl/handler/xslt_include_handler.hpp index 5a1d9f29..51af9bb5 100644 --- a/include/XSLT/impl/handler/xslt_include_handler.hpp +++ b/include/XSLT/impl/handler/xslt_include_handler.hpp @@ -113,8 +113,9 @@ public: { std::vector::iterator import = import_stack_.end()-1; size_t index = import_stack_.size() - 1; - context_->stylesheet().push_import_precedence(); + context_->push_import_precedence(); include_stylesheet(import_stack_.back()); + context_->pop_import_precedence(); import_stack_.erase(import_stack_.begin() + index); } // while ... } // unwind_imports diff --git a/include/XSLT/impl/handler/xslt_template_handler.hpp b/include/XSLT/impl/handler/xslt_template_handler.hpp index 972fe2e5..cd9ff72f 100755 --- a/include/XSLT/impl/handler/xslt_template_handler.hpp +++ b/include/XSLT/impl/handler/xslt_template_handler.hpp @@ -71,12 +71,14 @@ protected: if(match == "") return new Template(name, mode, - attributes["priority"]); + attributes["priority"], + context().precedence()); return new Template(context().xpath_match(match), name, mode, - atts.getValue("priority")); + atts.getValue("priority"), + context().precedence()); } // createContainer virtual bool createChild(const std::string& namespaceURI, diff --git a/include/XSLT/impl/handler/xslt_variable_handler.hpp b/include/XSLT/impl/handler/xslt_variable_handler.hpp index 79c1209a..91a0b323 100644 --- a/include/XSLT/impl/handler/xslt_variable_handler.hpp +++ b/include/XSLT/impl/handler/xslt_variable_handler.hpp @@ -16,7 +16,15 @@ class VariableHandler : public ItemContainerHandler public: VariableHandler(CompilationContext& context) : ItemContainerHandler(context), - has_select_(false) + has_select_(false), + precedence_(Precedence::FrozenPrecedence()) + { + } // VariableHandler + + VariableHandler(CompilationContext& context, const Precedence& precedence) : + ItemContainerHandler(context), + has_select_(false), + precedence_(precedence) { } // VariableHandler @@ -42,7 +50,7 @@ protected: } // if ... std::pair name = this->context().processInternalQName(attrs["name"]); - return new VType(name.first, name.second, xpath); + return new VType(name.first, name.second, xpath, precedence_); } // createContainer virtual void characters(const std::string& ch) @@ -58,6 +66,7 @@ protected: private: bool has_select_; + const Precedence precedence_; }; // class VariableHandler template @@ -65,7 +74,7 @@ class TopLevelVariableHandler : public VariableHandler { public: TopLevelVariableHandler(CompilationContext& context) : - VariableHandler(context) + VariableHandler(context, context.precedence()) { } // VariableHandler @@ -73,7 +82,7 @@ public: const std::string& localName, const std::string& qName) { - this->context().stylesheet().add_item(this->container()); + this->context().stylesheet().add_variable(this->container()); this->context().pop(); } // endElement diff --git a/include/XSLT/impl/xslt_compilation_context.hpp b/include/XSLT/impl/xslt_compilation_context.hpp index 75e3dcc6..632b2294 100755 --- a/include/XSLT/impl/xslt_compilation_context.hpp +++ b/include/XSLT/impl/xslt_compilation_context.hpp @@ -139,6 +139,20 @@ public: return ss.str(); } // autoNamespacePrefix + void push_import_precedence() + { + precedenceStack_.push(); + stylesheet_.push_import_precedence(); + } // push_import_precedence + + void pop_import_precedence() + { + } // pop_import_precedence + + const Precedence& precedence() const + { + return precedenceStack_.top(); + } // precedence private: // FunctionResolver @@ -185,6 +199,7 @@ private: std::stack*> handlerStack_; std::stack parentStack_; std::map namespaceRemap_; + PrecedenceStack precedenceStack_; CompilationContext(const CompilationContext&); mutable int autoNs_; diff --git a/include/XSLT/impl/xslt_compiled_stylesheet.hpp b/include/XSLT/impl/xslt_compiled_stylesheet.hpp index 856b1fb8..b3486238 100755 --- a/include/XSLT/impl/xslt_compiled_stylesheet.hpp +++ b/include/XSLT/impl/xslt_compiled_stylesheet.hpp @@ -35,9 +35,8 @@ public: virtual ~CompiledStylesheet() { // let's clean up! - for(ItemStack::const_iterator isi = items_.begin(), ise = items_.end(); isi != ise; ++isi) - for(ItemList::const_iterator ci = isi->begin(), ce = isi->end(); ci != ce; ++ci) - delete *ci; + for(VariableDeclList::const_iterator ci = topLevelVars_.begin(), ce = topLevelVars_.end(); ci != ce; ++ci) + delete *ci; for(ParamList::const_iterator pi = params_.begin(), pe = params_.end(); pi != pe; ++pi) delete *pi; for(TemplateList::const_iterator ti = all_templates_.begin(), te = all_templates_.end(); ti != te; ++ti) @@ -84,12 +83,8 @@ public: // set up variables and so forth for(ParamList::const_iterator pi = params_.begin(), pe = params_.end(); pi != pe; ++pi) (*pi)->declare(context); - for(ItemStack::const_iterator isi = items_.begin(), ise = items_.end(); isi != ise; ++isi) - { - for(ItemList::const_iterator ci = isi->begin(), ce = isi->end(); ci != ce; ++ci) - (*ci)->execute(initialNode, context); - context.pushVariablePrecedence(); - } // for ... + for(VariableDeclList::const_iterator ci = topLevelVars_.begin(), ce = topLevelVars_.end(); ci != ce; ++ci) + (*ci)->execute(initialNode, context); context.freezeTopLevel(); // go! @@ -127,12 +122,11 @@ public: void push_import_precedence() { templates_.push_back(ModeTemplates()); - items_.push_back(ItemList()); } // push_import_precedence - void add_item(Item* item) + void add_variable(Item* item) { - items_.back().push_back(item); + topLevelVars_.push_back(item); } // add_item void output_settings(const Output::Settings& settings) @@ -310,15 +304,14 @@ private: typedef std::vector TemplateStack; typedef std::map, Template*> NamedTemplates; - typedef std::vector ItemList; - typedef std::vector ItemStack; + typedef std::vector VariableDeclList; typedef std::vector ParamList; TemplateList all_templates_; NamedTemplates named_templates_; TemplateStack templates_; - ItemStack items_; + VariableDeclList topLevelVars_; ParamList params_; std::vector current_import_precedence_; diff --git a/include/XSLT/impl/xslt_execution_context.hpp b/include/XSLT/impl/xslt_execution_context.hpp index e4b5c78f..b1bdb101 100755 --- a/include/XSLT/impl/xslt_execution_context.hpp +++ b/include/XSLT/impl/xslt_execution_context.hpp @@ -24,6 +24,7 @@ public: virtual Arabica::XPath::XPathValue value(const DOM::Node& node, ExecutionContext& context, DOMSink& sink) const = 0; + virtual const Precedence& precedence() const = 0; private: Variable_declaration(const Variable_declaration&); @@ -40,7 +41,6 @@ public: stylesheet_(stylesheet), sink_(output.asOutput()), message_sink_(error_output), - variable_precedence_(), to_msg_(0) { xpathContext_.setVariableResolver(stack_); @@ -54,7 +54,6 @@ public: stack_(rhs.stack_), sink_(output.asOutput()), message_sink_(rhs.message_sink_), - variable_precedence_(rhs.variable_precedence_), to_msg_(false) { xpathContext_.setVariableResolver(stack_); @@ -79,8 +78,6 @@ public: void unpassParam(const std::string& name); void declareParam(const DOM::Node& node, const Variable_declaration& param); void declareVariable(const DOM::Node& node, const Variable_declaration& variable); - void pushVariablePrecedence() { variable_precedence_.push(); } - const Precedence& variablePrecedence() const { return variable_precedence_.top(); } void freezeTopLevel(); void injectGlobalScope(const Scope& scope); @@ -106,7 +103,6 @@ private: private: const CompiledStylesheet& stylesheet_; VariableStack stack_; - PrecedenceStack variable_precedence_; Arabica::XPath::ExecutionContext xpathContext_; Output& sink_; StreamSink message_sink_; @@ -129,7 +125,7 @@ public: virtual const std::string& namespace_uri() const { return var_.namespace_uri(); } virtual const std::string& name() const { return var_.name(); } - virtual const Precedence& precedence() const { return context_.variablePrecedence(); } + virtual const Precedence& precedence() const { return var_.precedence(); } virtual Arabica::XPath::XPathValue value() const { @@ -195,7 +191,6 @@ void ExecutionContext::declareVariable(const DOM::Node& node, const void ExecutionContext::freezeTopLevel() { stack_.freezeTopLevel(); - variable_precedence_.freeze(); } // freezeTopLevel void ExecutionContext::injectGlobalScope(const Scope& scope) diff --git a/include/XSLT/impl/xslt_param.hpp b/include/XSLT/impl/xslt_param.hpp index 8b147648..94954615 100644 --- a/include/XSLT/impl/xslt_param.hpp +++ b/include/XSLT/impl/xslt_param.hpp @@ -13,8 +13,9 @@ class Param : public Variable_impl public: Param(const std::string& namespace_uri, const std::string& name, - Arabica::XPath::XPathExpressionPtr select) : - Variable_impl(namespace_uri, name, select) + Arabica::XPath::XPathExpressionPtr select, + const Precedence& precedence) : + Variable_impl(namespace_uri, name, select, precedence) { } // Param diff --git a/include/XSLT/impl/xslt_precedence.hpp b/include/XSLT/impl/xslt_precedence.hpp index 6ba51a48..4f349be3 100755 --- a/include/XSLT/impl/xslt_precedence.hpp +++ b/include/XSLT/impl/xslt_precedence.hpp @@ -4,13 +4,13 @@ class Precedence { public: - static Precedence InitialPrecedence() + static const Precedence& InitialPrecedence() { static Precedence initial_(0); return initial_; } // Precedence - static Precedence FrozenPrecedence() + static const Precedence& FrozenPrecedence() { static Precedence frozen_(-1); return frozen_; @@ -74,7 +74,7 @@ public: PrecedenceStack() : stack_() { - stack_.push_back(Precedence::InitialPrecedence()); + stack_.push(Precedence::InitialPrecedence()); } // PrecedenceStack PrecedenceStack(const PrecedenceStack& rhs) : @@ -82,15 +82,17 @@ public: { } // PrecedenceStack - const Precedence& top() const { return stack_[stack_.size()-1]; } - void push() { stack_.push_back(top().nextGeneration(stack_.size())); } + const Precedence& top() const { return stack_.top(); } + void push() { stack_.push(top().nextGeneration(stack_.size())); } + void pop() { stack_.pop(); } void freeze() { - stack_.clear(); - stack_.push_back(Precedence::FrozenPrecedence()); + while(!stack_.empty()) + stack_.pop(); + stack_.push(Precedence::FrozenPrecedence()); } // freeze private: - std::vector stack_; + std::stack stack_; }; // class PrecedenceStack #endif diff --git a/include/XSLT/impl/xslt_template.hpp b/include/XSLT/impl/xslt_template.hpp index 43f264aa..c1c4e9f1 100755 --- a/include/XSLT/impl/xslt_template.hpp +++ b/include/XSLT/impl/xslt_template.hpp @@ -14,20 +14,24 @@ class Template : public ItemContainer public: Template(const std::pair& name, const std::pair& mode, - const std::string& priority) : + const std::string& priority, + const Precedence& precedence) : matches_(), name_(name), - mode_(mode) + mode_(mode), + precedence_(precedence) { } // Template Template(const std::vector >& matches, const std::pair& name, const std::pair& mode, - const std::string& priority) : + const std::string& priority, + const Precedence& precedence) : matches_(matches), name_(name), - mode_(mode) + mode_(mode), + precedence_(precedence) { if(!priority.empty()) { @@ -50,11 +54,13 @@ public: bool has_name() const { return !name_.second.empty(); } const std::pair& name() const { return name_; } const std::pair& mode() const { return mode_; } + const Precedence& precedence() const { return precedence_; } private: std::vector > matches_; std::pair name_; std::pair mode_; + const Precedence precedence_; }; // class Template } // namespace XSLT diff --git a/include/XSLT/impl/xslt_top_level_param.hpp b/include/XSLT/impl/xslt_top_level_param.hpp index 214d0e53..1fe87476 100644 --- a/include/XSLT/impl/xslt_top_level_param.hpp +++ b/include/XSLT/impl/xslt_top_level_param.hpp @@ -33,6 +33,7 @@ public: { return value_; } // value + virtual const Precedence& precedence() const { return Precedence::InitialPrecedence(); } private: static DOM::Node null_node; diff --git a/include/XSLT/impl/xslt_variable.hpp b/include/XSLT/impl/xslt_variable.hpp index c7d5bd8b..7e8aabb3 100644 --- a/include/XSLT/impl/xslt_variable.hpp +++ b/include/XSLT/impl/xslt_variable.hpp @@ -13,8 +13,9 @@ class Variable : public Variable_impl public: Variable(const std::string& namespace_uri, const std::string& name, - Arabica::XPath::XPathExpressionPtr select) : - Variable_impl(namespace_uri, name, select) + Arabica::XPath::XPathExpressionPtr select, + const Precedence precedence) : + Variable_impl(namespace_uri, name, select, precedence) { } // Variable diff --git a/include/XSLT/impl/xslt_variable_impl.hpp b/include/XSLT/impl/xslt_variable_impl.hpp index db42e398..977f028c 100644 --- a/include/XSLT/impl/xslt_variable_impl.hpp +++ b/include/XSLT/impl/xslt_variable_impl.hpp @@ -16,10 +16,12 @@ class Variable_impl : public ItemContainer, public Variable_declaration protected: Variable_impl(const std::string& namespace_uri, const std::string& name, - Arabica::XPath::XPathExpressionPtr select) : + Arabica::XPath::XPathExpressionPtr select, + const Precedence& precedence) : namespace_uri_(namespace_uri), name_(name), - select_(select) + select_(select), + precedence_(precedence) { } // Variable_impl @@ -48,10 +50,13 @@ public: return Arabica::XPath::NodeSetValue >::createValue(nodeset); } // value + virtual const Precedence& precedence() const { return precedence_; } + private: std::string namespace_uri_; std::string name_; Arabica::XPath::XPathExpressionPtr select_; + Precedence precedence_; }; // Variable_impl } // namespace XSLT diff --git a/include/XSLT/impl/xslt_with_param.hpp b/include/XSLT/impl/xslt_with_param.hpp index c37f41aa..ac590103 100644 --- a/include/XSLT/impl/xslt_with_param.hpp +++ b/include/XSLT/impl/xslt_with_param.hpp @@ -13,8 +13,9 @@ class WithParam : public Variable_impl public: WithParam(const std::string& namespace_uri, const std::string& name, - Arabica::XPath::XPathExpressionPtr select) : - Variable_impl(namespace_uri, name, select) + Arabica::XPath::XPathExpressionPtr select, + const Precedence& precedence) : + Variable_impl(namespace_uri, name, select, precedence) { } // WithParam diff --git a/vs9/example_XSLT_Mangle.vcproj b/vs9/example_XSLT_Mangle.vcproj index 53bd7eac..e603fe11 100644 --- a/vs9/example_XSLT_Mangle.vcproj +++ b/vs9/example_XSLT_Mangle.vcproj @@ -224,6 +224,10 @@ RelativePath="..\include\Xslt\impl\xslt_compilation_context.hpp" > + + @@ -268,6 +272,10 @@ RelativePath="..\include\Xslt\impl\xslt_param.hpp" > + +