From 8cb5109ac16d4dbc259e87668fc690e411ac8f16 Mon Sep 17 00:00:00 2001 From: jez Date: Thu, 26 Feb 2009 10:16:49 +0000 Subject: [PATCH] keys now look something up. yay! --- include/XPath/impl/xpath_axis_enumerator.hpp | 2 +- include/XSLT/impl/xslt_functions.hpp | 2 +- include/XSLT/impl/xslt_key.hpp | 35 +++++++++++++++----- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/include/XPath/impl/xpath_axis_enumerator.hpp b/include/XPath/impl/xpath_axis_enumerator.hpp index ba09a589..dce0d3f6 100644 --- a/include/XPath/impl/xpath_axis_enumerator.hpp +++ b/include/XPath/impl/xpath_axis_enumerator.hpp @@ -37,7 +37,7 @@ template AxisWalker* CreateAxis(const DOM::Node& context) { return new axis_walker(context); } } // namespace impl -template +template > class AxisEnumerator { typedef impl::AxisWalker* (*CreateAxisPtr)(const DOM::Node& context); diff --git a/include/XSLT/impl/xslt_functions.hpp b/include/XSLT/impl/xslt_functions.hpp index 996333ed..b6b83891 100644 --- a/include/XSLT/impl/xslt_functions.hpp +++ b/include/XSLT/impl/xslt_functions.hpp @@ -87,7 +87,7 @@ public: std::string id = a1.asString(); std::string clarkName = XML::QualifiedName::parseQName(keyname, true, UriMapper(namespaces_)).clarkName(); - return new Arabica::XPath::NodeSetValue(keys_.lookup(clarkName, id)); + return new Arabica::XPath::NodeSetValue(keys_.lookup(clarkName, id, executionContext)); } // evaluate private: diff --git a/include/XSLT/impl/xslt_key.hpp b/include/XSLT/impl/xslt_key.hpp index 6d35bb64..395f1eb2 100644 --- a/include/XSLT/impl/xslt_key.hpp +++ b/include/XSLT/impl/xslt_key.hpp @@ -1,6 +1,8 @@ #ifndef ARABICA_XSLT_KEY_HPP #define ARABICA_XSLT_KEY_HPP +#include "xslt_execution_context.hpp" + namespace Arabica { namespace XSLT @@ -19,10 +21,11 @@ public: { } // Key - Arabica::XPath::NodeSet lookup(const std::string& value) const + Arabica::XPath::NodeSet lookup(const std::string& value, + const Arabica::XPath::ExecutionContext& context) const { if(!populated_) - populate(); + populate(context); NodeMap::const_iterator f = nodes_.find(value); if(f == nodes_.end()) @@ -32,9 +35,24 @@ public: } // lookup private: - void populate() const + void populate(const Arabica::XPath::ExecutionContext& context) const { - std::cerr << "Populating key map " << std::endl; + typedef XPath::AxisEnumerator AxisEnum; + + DOM::Node current = XPath::impl::get_owner_document(context.currentNode()); + + for(AxisEnum ae(current, XPath::DESCENDANT_OR_SELF); *ae != 0; ++ae) + { + DOM::Node node = *ae; + for(MatchExprList::const_iterator me = matches_.begin(), mee = matches_.end(); me != mee; ++me) + if(me->evaluate(node, context)) + { + std::string id = use_.evaluateAsString(node, context); + nodes_[id].push_back(node); + break; + } // if ... + } // for + populated_ = true; } // populate @@ -43,7 +61,7 @@ private: mutable bool populated_; typedef std::map > NodeMap; - NodeMap nodes_; + mutable NodeMap nodes_; }; // class Key class DeclaredKeys @@ -63,18 +81,19 @@ public: } // add_key Arabica::XPath::NodeSet lookup(const std::string& name, - const std::string& id) const + const std::string& id, + const Arabica::XPath::ExecutionContext& context) const { const Keys::const_iterator k = keys_.find(name); if(k == keys_.end()) throw SAX::SAXException("No key named '" + name + "' has been defined."); if(k->second.size() == 1) - return k->second[0]->lookup(id); + return k->second[0]->lookup(id, context); Arabica::XPath::NodeSet nodes; for(KeyList::const_iterator key = k->second.begin(), keye = k->second.end(); key != keye; ++key) - nodes.push_back((*key)->lookup(id)); + nodes.push_back((*key)->lookup(id, context)); nodes.sort(); return nodes; } // lookup