diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/pugixml.cpp | 56 | ||||
| -rw-r--r-- | src/pugixml.hpp | 6 | 
2 files changed, 45 insertions, 17 deletions
| diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 1d9dcfe..6f230dd 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -10581,6 +10581,25 @@ PUGI__NS_BEGIN  		return impl->root->eval_string(c, sd.stack);  	} + +	PUGI__FN impl::xpath_ast_node* evaluate_node_set_prepare(xpath_query_impl* impl) +	{ +		if (!impl) return 0; + +		if (impl->root->rettype() != xpath_type_node_set) +		{ +		#ifdef PUGIXML_NO_EXCEPTIONS +			return 0; +		#else +			xpath_parse_result res; +			res.error = "Expression does not evaluate to node set"; + +			throw xpath_exception(res); +		#endif +		} + +		return impl->root; +	}  PUGI__NS_END  namespace pugi @@ -11082,22 +11101,9 @@ namespace pugi  	PUGI__FN xpath_node_set xpath_query::evaluate_node_set(const xpath_node& n) const  	{ -		if (!_impl) return xpath_node_set(); - -		impl::xpath_ast_node* root = static_cast<impl::xpath_query_impl*>(_impl)->root; - -		if (root->rettype() != xpath_type_node_set) -		{ -		#ifdef PUGIXML_NO_EXCEPTIONS -			return xpath_node_set(); -		#else -			xpath_parse_result res; -			res.error = "Expression does not evaluate to node set"; +		impl::xpath_ast_node* root = impl::evaluate_node_set_prepare(static_cast<impl::xpath_query_impl*>(_impl)); +		if (!root) return xpath_node_set(); -			throw xpath_exception(res); -		#endif -		} -		  		impl::xpath_context c(n, 1, 1);  		impl::xpath_stack_data sd; @@ -11110,6 +11116,23 @@ namespace pugi  		return xpath_node_set(r.begin(), r.end(), r.type());  	} +	PUGI__FN xpath_node xpath_query::evaluate_node(const xpath_node& n) const +	{ +		impl::xpath_ast_node* root = impl::evaluate_node_set_prepare(static_cast<impl::xpath_query_impl*>(_impl)); +		if (!root) return xpath_node(); + +		impl::xpath_context c(n, 1, 1); +		impl::xpath_stack_data sd; + +	#ifdef PUGIXML_NO_EXCEPTIONS +		if (setjmp(sd.error_handler)) return xpath_node(); +	#endif + +		impl::xpath_node_set_raw r = root->eval_node_set(c, sd.stack); + +		return r.first(); +	} +  	PUGI__FN const xpath_parse_result& xpath_query::result() const  	{  		return _result; @@ -11137,8 +11160,7 @@ namespace pugi  	PUGI__FN xpath_node xml_node::select_single_node(const xpath_query& query) const  	{ -		xpath_node_set s = query.evaluate_node_set(*this); -		return s.empty() ? xpath_node() : s.first(); +		return query.evaluate_node(*this);  	}  	PUGI__FN xpath_node_set xml_node::select_nodes(const char_t* query, xpath_variable_set* variables) const diff --git a/src/pugixml.hpp b/src/pugixml.hpp index 69b2cb2..2947bf4 100644 --- a/src/pugixml.hpp +++ b/src/pugixml.hpp @@ -1134,6 +1134,12 @@ namespace pugi  		// If PUGIXML_NO_EXCEPTIONS is defined, returns empty node set instead.  		xpath_node_set evaluate_node_set(const xpath_node& n) const; +		// Evaluate expression as node set in the specified context. +		// Return first node in document order, or empty node if node set is empty. +		// If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on type mismatch and std::bad_alloc on out of memory errors. +		// If PUGIXML_NO_EXCEPTIONS is defined, returns empty node instead. +		xpath_node evaluate_node(const xpath_node& n) const; +  		// Get parsing result (used to get compilation errors in PUGIXML_NO_EXCEPTIONS mode)  		const xpath_parse_result& result() const; | 
