diff options
| -rw-r--r-- | src/pugixml.cpp | 10 | ||||
| -rw-r--r-- | tests/test_xpath_paths.cpp | 8 | 
2 files changed, 17 insertions, 1 deletions
diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 67591a3..f0bfc31 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -9765,6 +9765,14 @@ PUGI__NS_BEGIN  			if (_right) _right->optimize(alloc);  			if (_next) _next->optimize(alloc); +			// Rewrite [position()=expr] with [expr] +			// Note that this step has to go before classification to recognize [position()=1] +			if ((_type == ast_filter || _type == ast_predicate) && +				_right->_type == ast_op_equal && _right->_left->_type == ast_func_position && _right->_right->_rettype == xpath_type_number) +			{ +				_right = _right->_right; +			} +  			// Classify filter/predicate ops to perform various optimizations during evaluation  			if (_type == ast_filter || _type == ast_predicate)  			{ @@ -9772,7 +9780,7 @@ PUGI__NS_BEGIN  				if (_right->_type == ast_number_constant && _right->_data.number == 1.0)  					_test = predicate_constant_one; -				else if (_right->_rettype == xpath_type_number && (_right->_type == ast_number_constant || _right->_type == ast_variable)) +				else if (_right->_rettype == xpath_type_number && (_right->_type == ast_number_constant || _right->_type == ast_variable || _right->_type == ast_func_last))  					_test = predicate_constant;  				else if (_right->_rettype != xpath_type_number && _right->is_posinv_expr())  					_test = predicate_posinv; diff --git a/tests/test_xpath_paths.cpp b/tests/test_xpath_paths.cpp index 046592a..df0dfa4 100644 --- a/tests/test_xpath_paths.cpp +++ b/tests/test_xpath_paths.cpp @@ -475,6 +475,14 @@ TEST_XML(xpath_paths_predicate_constant_boolean, "<node><chapter/><chapter/><cha  	CHECK_XPATH_NODESET_VAR(n, STR("following-sibling::chapter[$true]"), &set) % 6 % 7;  } +TEST_XML(xpath_paths_predicate_position_eq, "<node><chapter/><chapter/><chapter>3</chapter><chapter/><chapter/></node>") +{ +	CHECK_XPATH_NODESET(doc, STR("node/chapter[position()=1]")) % 3; +	CHECK_XPATH_NODESET(doc, STR("node/chapter[position()=2+2]")) % 7; +	CHECK_XPATH_NODESET(doc, STR("node/chapter[position()=last()]")) % 8; +	CHECK_XPATH_NODESET(doc, STR("node/chapter[position()=string()]")) % 5; +} +  TEST_XML(xpath_paths_predicate_several, "<node><employee/><employee secretary=''/><employee assistant=''/><employee secretary='' assistant=''/><employee assistant='' secretary=''/></node>")  {  	xml_node n = doc.child(STR("node"));  | 
