From 3244c693f8db9afb1845f5e6de3cb1807e68003d Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 15 May 2007 05:43:46 +0000 Subject: Started working on an XPath visitor class --- src/xpath.h | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) (limited to 'src/xpath.h') diff --git a/src/xpath.h b/src/xpath.h index ccec7b0a..f17d3ee8 100644 --- a/src/xpath.h +++ b/src/xpath.h @@ -212,6 +212,55 @@ private: }; public: + class path_t : public noncopyable + { + public: // jww (2007-05-14): for testing + typedef function visitor_t; + typedef function predicate_t; + + struct element_t + { + variant ident; + + bool recurse; + predicate_t predicate; + }; + + std::list elements; + + typedef std::list::const_iterator element_iterator; + + struct node_appender_t { + value_t::sequence_t& sequence; + node_appender_t(value_t::sequence_t& _sequence) + : sequence(_sequence) {} + void operator()(node_t& node) { + sequence.push_back(&node); + } + }; + + public: + path_t(const xpath_t& path_expr); + + void find_all(value_t::sequence_t& result, + node_t& start, scope_t * scope) { + visit(start, scope, node_appender_t(result)); + } + + void visit(node_t& start, scope_t * scope, + const function& func) { + if (elements.begin() != elements.end()) + walk_elements(start, elements.begin(), scope, func); + } + + private: + void walk_elements(node_t& start, const element_iterator& element, + scope_t * scope, const function& func); + void check_element(node_t& start, const element_iterator& element, + scope_t * scope, const function& func); + }; + struct op_t : public noncopyable { enum kind_t { @@ -366,6 +415,22 @@ public: data = val; } +#if 0 + bool is_path() const { + return kind == PATH; + } + path_t& as_path() { + assert(kind == PATH); + return boost::get(data); + } + const path_t& as_path() const { + return const_cast(this)->as_path(); + } + void set_path(const path_t& val) { + data = val; + } +#endif + ptr_op_t& as_op() { assert(kind > TERMINALS); return boost::get(data); @@ -437,6 +502,20 @@ public: void dump(std::ostream& out, const int depth) const; }; + class op_predicate + { + ptr_op_t op; + + public: + op_predicate(ptr_op_t _op) : op(_op) {} + + bool operator()(node_t& node, scope_t * scope) { + value_t context_node(&node); + xpath_t result(op->compile(context_node, scope, true)); + return result.ptr->as_value().to_boolean(); + } + }; + public: ptr_op_t ptr; -- cgit v1.2.3