#ifndef ARABICA_XSLT_COMPILATION_CONTEXT #define ARABICA_XSLT_COMPILATION_CONTEXT #include #include #include #include namespace Arabica { namespace XSLT { class Stylesheet; class ItemContainer; class CompilationContext { public: CompilationContext(SAX::NamespaceTracker& parser, Arabica::XPath::XPath& xpathCompiler, Stylesheet& stylesheet) : parser_(parser), xpath_(xpathCompiler), stylesheet_(stylesheet), autoNs_(1) { } // CompilationContext ~CompilationContext() { // delete any left over - will only be the case if unwinding while(handlerStack_.size() > 1) { delete handlerStack_.top(); handlerStack_.pop(); } // while ... } // ~CompilationContext void root(SAX::DefaultHandler& root) { handlerStack_.push(&root); } // root SAX::basic_XMLReader& parser() const { return parser_; } const Arabica::XPath::XPath& xpath() const { return xpath_; } Stylesheet& stylesheet() const { return stylesheet_; } std::pair processQName(const std::string& qName) const { return parser_.process(qName); } // processQName std::string makeAbsolute(const std::string& href) const { SAX::XMLBaseTracker* tracker = static_cast*>(parser_.getParent()); return tracker->makeAbsolute(href); } // makeAbsolute void push(ItemContainer* parent, SAX::DefaultHandler* newHandler, const std::string& namespaceURI, const std::string& localName, const std::string& qName, const SAX::Attributes& atts) { parentStack_.push(parent); handlerStack_.push(newHandler); parser_.setContentHandler(*newHandler); newHandler->startElement(namespaceURI, qName, localName, atts); } // push void pop() { parentStack_.pop(); delete handlerStack_.top(); handlerStack_.pop(); parser_.setContentHandler(*handlerStack_.top()); } // pop ItemContainer& parentContainer() const { return *parentStack_.top(); } // parentContainer SAX::DefaultHandler& parentHandler() const { return *handlerStack_.top(); } // parentHandler std::map inScopeNamespaces() const { return parser_.inScopeNamespaces(); } // inScopeNamespaces void addNamespaceAlias(const std::string& stylesheet_namespace, const std::string& result_prefix, const std::string& result_namespace) { namespaceRemap_[stylesheet_namespace] = std::make_pair(result_prefix, result_namespace); } // addNamespaceAlias bool isRemapped(const std::string& namespaceURI) const { return namespaceRemap_.find(namespaceURI) != namespaceRemap_.end(); } // isRemapped const std::pair& remappedNamespace(const std::string& namespaceURI) { return namespaceRemap_[namespaceURI]; } // remappedNamespace std::string autoNamespacePrefix() const { std::ostringstream ss; ss << "auto-ns" << autoNs_++; return ss.str(); } // autoNamespacePrefix private: typedef std::pair Namespace; SAX::NamespaceTracker& parser_; const Arabica::XPath::XPath& xpath_; Stylesheet& stylesheet_; std::stack handlerStack_; std::stack parentStack_; std::map namespaceRemap_; CompilationContext(const CompilationContext&); mutable int autoNs_; }; // class CompilationContext } // namespace XSLT } // namespace Arabica #endif // ARABICA_XSLT_COMPILATION_CONTEXT