#ifndef ARABICA_XSLT_APPLY_TEMPLATES_HPP #define ARABICA_XSLT_APPLY_TEMPLATES_HPP #include "xslt_stylesheet.hpp" #include "xslt_sort.hpp" #include "xslt_with_param.hpp" namespace Arabica { namespace XSLT { class ApplyTemplates : public Item, public Sortable, public WithParamable { public: ApplyTemplates(Arabica::XPath::XPathExpressionPtr select, const std::pair& mode) : select_(select), mode_(mode) { } // ApplyTemplates virtual void execute(const DOM::Node& node, ExecutionContext& context) const { ParamPasser passer(*this, node, context); if(!has_sort() && select_ == 0) { if(node.hasChildNodes()) context.stylesheet().applyTemplates(node.getChildNodes(), context, mode_); return; } Arabica::XPath::NodeSet nodes; if(select_ == 0) for(DOM::Node n = node.getFirstChild(); n != 0; n = n.getNextSibling()) nodes.push_back(n); else { Arabica::XPath::XPathValuePtr value = select_->evaluate(node, context.xpathContext()); if(value->type() != Arabica::XPath::NODE_SET) throw std::runtime_error("apply-templates select expression is not a node-set"); nodes = value->asNodeSet(); } sort(node, nodes, context); context.stylesheet().applyTemplates(nodes, context, mode_); } // execute private: Arabica::XPath::XPathExpressionPtr select_; const std::pair mode_; }; // class ApplyTemplates } // namespace XSLT } // namespace Arabica #endif // ARABICA_XSLT_APPLY_TEMPLATES_HPP