keys stored on a per-document basis, as per the end of rec 12.2

This commit is contained in:
jez 2009-02-26 10:30:16 +00:00
parent 8cb5109ac1
commit 4af8e6472e

View file

@ -16,26 +16,32 @@ public:
Key(MatchExprList& matches, Key(MatchExprList& matches,
Arabica::XPath::XPathExpression<std::string>& use) : Arabica::XPath::XPathExpression<std::string>& use) :
matches_(matches), matches_(matches),
use_(use), use_(use)
populated_(false)
{ {
} // Key } // Key
Arabica::XPath::NodeSet<std::string> lookup(const std::string& value, Arabica::XPath::NodeSet<std::string> lookup(const std::string& value,
const Arabica::XPath::ExecutionContext<std::string>& context) const const Arabica::XPath::ExecutionContext<std::string>& context) const
{ {
if(!populated_) DOM::Node<std::string> doc = XPath::impl::get_owner_document(context.currentNode());
populate(context); DocumentNodeMap::const_iterator nm = nodesPerDocument_.find(doc.underlying_impl());
if(nm == nodesPerDocument_.end())
populate(nodesPerDocument_[doc.underlying_impl()], context);
NodeMap::const_iterator f = nodes_.find(value); const NodeMap& nodes = nodesPerDocument_[doc.underlying_impl()];
if(f == nodes_.end()) NodeMap::const_iterator f = nodes.find(value);
if(f == nodes.end())
return Arabica::XPath::NodeSet<std::string>(0); return Arabica::XPath::NodeSet<std::string>(0);
return f->second; return f->second;
} // lookup } // lookup
private: private:
void populate(const Arabica::XPath::ExecutionContext<std::string>& context) const typedef std::map<std::string, Arabica::XPath::NodeSet<std::string> > NodeMap;
typedef std::map<DOM::Node_impl<std::string, Arabica::default_string_adaptor<std::string> >*, NodeMap> DocumentNodeMap;
void populate(NodeMap& nodes,
const Arabica::XPath::ExecutionContext<std::string>& context) const
{ {
typedef XPath::AxisEnumerator<std::string> AxisEnum; typedef XPath::AxisEnumerator<std::string> AxisEnum;
@ -48,20 +54,16 @@ private:
if(me->evaluate(node, context)) if(me->evaluate(node, context))
{ {
std::string id = use_.evaluateAsString(node, context); std::string id = use_.evaluateAsString(node, context);
nodes_[id].push_back(node); nodes[id].push_back(node);
break; break;
} // if ... } // if ...
} // for } // for
populated_ = true;
} // populate } // populate
MatchExprList matches_; MatchExprList matches_;
Arabica::XPath::XPathExpression<std::string> use_; Arabica::XPath::XPathExpression<std::string> use_;
mutable bool populated_; mutable DocumentNodeMap nodesPerDocument_;
typedef std::map<std::string, Arabica::XPath::NodeSet<std::string> > NodeMap;
mutable NodeMap nodes_;
}; // class Key }; // class Key
class DeclaredKeys class DeclaredKeys