diff --git a/include/XSLT/impl/xslt_compilation_context.hpp b/include/XSLT/impl/xslt_compilation_context.hpp index 504df606..903190b4 100755 --- a/include/XSLT/impl/xslt_compilation_context.hpp +++ b/include/XSLT/impl/xslt_compilation_context.hpp @@ -175,7 +175,7 @@ private: return new DocumentFunction(parser_.currentBase(), argExprs); // key if(name == "key") - return new KeyFunction(argExprs); + return new KeyFunction(stylesheet_.keys(), argExprs); // format-number if((name == "current") && (current_allowed_)) return new CurrentFunction(argExprs); diff --git a/include/XSLT/impl/xslt_compiled_stylesheet.hpp b/include/XSLT/impl/xslt_compiled_stylesheet.hpp index 24ead12a..2ae52f3a 100755 --- a/include/XSLT/impl/xslt_compiled_stylesheet.hpp +++ b/include/XSLT/impl/xslt_compiled_stylesheet.hpp @@ -92,6 +92,8 @@ public: } // execute //////////////////////////////////////// + const DeclaredKeys& keys() const { return keys_; } + void add_template(Template* templat) { typedef std::vector > MatchExprList; @@ -125,7 +127,7 @@ public: void add_key(const std::pair& name, Key* key) { - std::cerr << "Added key " << name.second << std::endl; + keys_.add(name, key); } // add_key void output_settings(const Output::Settings& settings) @@ -316,6 +318,7 @@ private: NamedTemplates named_templates_; TemplateStack templates_; VariableDeclList topLevelVars_; + DeclaredKeys keys_; ParamList params_; mutable std::pair current_mode_; diff --git a/include/XSLT/impl/xslt_functions.hpp b/include/XSLT/impl/xslt_functions.hpp index 80e8b979..1eb60292 100644 --- a/include/XSLT/impl/xslt_functions.hpp +++ b/include/XSLT/impl/xslt_functions.hpp @@ -65,9 +65,13 @@ class KeyFunction : public Arabica::XPath::XPathFunction typedef Arabica::XPath::XPathFunction baseT; public: - KeyFunction(/* the keys, */ + KeyFunction(const DeclaredKeys& keys, + /* also need to pass current namespace context, so can resolve qnames, */ const std::vector >& args) : - Arabica::XPath::XPathFunction(2, 2, args) { } + Arabica::XPath::XPathFunction(2, 2, args), + keys_(keys) + { + } // KeyFunction virtual Arabica::XPath::ValueType type() const { return Arabica::XPath::NODE_SET; } @@ -83,6 +87,8 @@ public: throw Arabica::XPath::UnsupportedException("key(" + keyname + ", " + id + ")"); } // evaluate +private: + const DeclaredKeys& keys_; }; // class KeyFunction // string format-number(number, string, string?) diff --git a/include/XSLT/impl/xslt_key.hpp b/include/XSLT/impl/xslt_key.hpp index 5721371b..c048b5c1 100644 --- a/include/XSLT/impl/xslt_key.hpp +++ b/include/XSLT/impl/xslt_key.hpp @@ -19,14 +19,14 @@ public: { } // Key - Arabica::DOM::Node lookup(const std::string& value) const + Arabica::XPath::NodeSet lookup(const std::string& value) const { if(!populated_) populate(); NodeMap::const_iterator f = nodes_.find(value); if(f == nodes_.end()) - return DOM::Node(0); + return Arabica::XPath::NodeSet(0); return f->second; } // lookup @@ -42,10 +42,53 @@ private: Arabica::XPath::XPathExpression use_; mutable bool populated_; - typedef std::map > NodeMap; + typedef std::map > NodeMap; NodeMap nodes_; }; // class Key +class DeclaredKeys +{ +public: + DeclaredKeys() { } + ~DeclaredKeys() + { + for(Keys::const_iterator i = keys_.begin(), ie = keys_.end(); i != ie; ++i) + for(KeyList::const_iterator k = i->second.begin(), ke = i->second.end(); k != ke; ++k) + delete (*k); + } // ~DeclaredKeys + + void add(const std::pair& name, Key* key) + { + keys_[name].push_back(key); + } // add_key + + Arabica::XPath::NodeSet lookup(const std::pair& name, + const std::string& id) const + { + const Keys::const_iterator k = keys_.find(name); + if(k == keys_.end()) + throw SAX::SAXException("No key named '" + name.second + "' has been defined."); + + //if(k->second.size() == 0) + return k->second[0]->lookup(id); + + //Arabica::XPath::NodeSet nodes; + //for(KeyList::const_iterator k = i->second.begin(), ke = i->second.end(); k != ke; ++k) + //nodes.a + //return k->second.lookup(id); + } // lookup + +private: + typedef std::vector KeyList; + typedef std::map, KeyList> Keys; + + Keys keys_; + + DeclaredKeys(const DeclaredKeys&); + DeclaredKeys& operator=(const DeclaredKeys&); + bool operator==(const DeclaredKeys&) const; +}; // class DeclaredKeys + } // namespace XSLT } // namespace Arabica