diff --git a/src/libs/zbxjson/jsonpath.c b/src/libs/zbxjson/jsonpath.c
index 98b73173d3..38f40ff459 100644
--- a/src/libs/zbxjson/jsonpath.c
+++ b/src/libs/zbxjson/jsonpath.c
@@ -31,10 +31,20 @@
 ZBX_VECTOR_DECL(var, zbx_variant_t)
 ZBX_VECTOR_IMPL(var, zbx_variant_t)
 
+typedef struct
+{
+	char		*name;
+	const char	*value;
+}
+zbx_json_element_t;
+
+ZBX_VECTOR_DECL(json, zbx_json_element_t)
+ZBX_VECTOR_IMPL(json, zbx_json_element_t)
+
 static int	jsonpath_query_object(const struct zbx_json_parse *jp_root, const struct zbx_json_parse *jp,
-		const zbx_jsonpath_t *jsonpath, int path_depth, zbx_vector_str_t *objects);
+		const zbx_jsonpath_t *jsonpath, int path_depth, zbx_vector_json_t *objects);
 static int	jsonpath_query_array(const struct zbx_json_parse *jp_root, const struct zbx_json_parse *jp,
-		const zbx_jsonpath_t *jsonpath, int path_depth, zbx_vector_str_t *objects);
+		const zbx_jsonpath_t *jsonpath, int path_depth, zbx_vector_json_t *objects);
 
 typedef struct
 {
@@ -78,6 +88,25 @@ static int	jsonpath_token_group(int type)
 	return jsonpath_tokens[type].group;
 }
 
+/* json element vector support */
+static void	zbx_vector_json_add_element(zbx_vector_json_t *elements, const char *name, const char *value)
+{
+	zbx_json_element_t	el;
+
+	el.name = zbx_strdup(NULL, name);
+	el.value = value;
+	zbx_vector_json_append(elements, el);
+}
+
+static void	zbx_vector_json_clear_ext(zbx_vector_json_t *elements)
+{
+	int	i;
+
+	for (i = 0; i < elements->values_num; i++)
+		zbx_free(elements->values[i].name);
+	zbx_vector_json_clear(elements);
+}
+
 /******************************************************************************
  *                                                                            *
  * Function: zbx_jsonpath_error                                               *
@@ -1254,6 +1283,32 @@ static int	jsonpath_parse_dot_segment(const char *start, zbx_jsonpath_t *jsonpat
 	return zbx_jsonpath_error(start);
 }
 
+/******************************************************************************
+ *                                                                            *
+ * Function: jsonpath_parse_name_reference                                    *
+ *                                                                            *
+ * Purpose: parse jsonpath name reference ~                                   *
+ *                                                                            *
+ * Parameters: jsonpath  - [IN/OUT] the jsonpath                              *
+ *             next      - [OUT] a pointer to the next character after parsed *
+ *                               segment                                      *
+ *                                                                            *
+ * Return value: SUCCEED - the segment was parsed successfully                *
+ *               FAIL    - otherwise                                          *
+ *                                                                            *
+ ******************************************************************************/
+static int	jsonpath_parse_name_reference(zbx_jsonpath_t *jsonpath, const char **next)
+{
+	zbx_jsonpath_segment_t	*segment;
+
+	segment = &jsonpath->segments[jsonpath->segments_num];
+	jsonpath->segments_num++;
+	segment->type = ZBX_JSONPATH_SEGMENT_FUNCTION;
+	segment->data.function.type = ZBX_JSONPATH_FUNCTION_NAME;
+	(*next)++;
+	return SUCCEED;
+}
+
 /******************************************************************************
  *                                                                            *
  * Function: jsonpath_pointer_to_jp                                           *
@@ -1292,15 +1347,14 @@ static int	jsonpath_pointer_to_jp(const char *pnext, struct zbx_json_parse *jp)
  *             pnext      - [IN] a pointer to object/array/value in json data *
  *             jsonpath   - [IN] the jsonpath                                 *
  *             path_depth - [IN] the jsonpath segment to match                *
- *             objects    - [OUT] pointers to the matched objects in json     *
- *                                data                                        *
+ *             objects    - [OUT] the matched json elements (name, value)     *
  *                                                                            *
  * Return value: SUCCEED - the data were queried successfully                 *
  *               FAIL    - otherwise                                          *
  *                                                                            *
  ******************************************************************************/
 static int	jsonpath_query_contents(const struct zbx_json_parse *jp_root, const char *pnext,
-		const zbx_jsonpath_t *jsonpath, int path_depth, zbx_vector_str_t *objects)
+		const zbx_jsonpath_t *jsonpath, int path_depth, zbx_vector_json_t *objects)
 {
 	struct zbx_json_parse	jp_child;
 
@@ -1327,25 +1381,25 @@ static int	jsonpath_query_contents(const struct zbx_json_parse *jp_root, const c
  * Purpose: query next segment                                                *
  *                                                                            *
  * Parameters: jp_root    - [IN] the document root                            *
+ *             name       - [IN] name or index of the next json element       *
  *             pnext      - [IN] a pointer to object/array/value in json data *
  *             jsonpath   - [IN] the jsonpath                                 *
  *             path_depth - [IN] the jsonpath segment to match                *
- *             objects    - [OUT] pointers to the matched objects in json     *
- *                                data                                        *
+ *             objects    - [OUT] the matched json elements (name, value)     *
  *                                                                            *
  * Return value: SUCCEED - the segment was queried successfully               *
  *               FAIL    - otherwise                                          *
  *                                                                            *
  ******************************************************************************/
-static int	jsonpath_query_next_segment(const struct zbx_json_parse *jp_root, const char *pnext,
-		const zbx_jsonpath_t *jsonpath, int path_depth, zbx_vector_str_t *objects)
+static int	jsonpath_query_next_segment(const struct zbx_json_parse *jp_root, const char *name, const char *pnext,
+		const zbx_jsonpath_t *jsonpath, int path_depth, zbx_vector_json_t *objects)
 {
 	/* check if jsonpath end has been reached, so we have found matching data */
 	/* (functions are processed afterwards)                                   */
 	if (++path_depth == jsonpath->segments_num ||
 			ZBX_JSONPATH_SEGMENT_FUNCTION == jsonpath->segments[path_depth].type)
 	{
-		zbx_vector_str_append(objects, (char *)pnext);
+		zbx_vector_json_add_element(objects, name, pnext);
 		return SUCCEED;
 	}
 
@@ -1360,20 +1414,20 @@ static int	jsonpath_query_next_segment(const struct zbx_json_parse *jp_root, con
  * Purpose: match object value name against jsonpath segment name list        *
  *                                                                            *
  * Parameters: jp_root    - [IN] the document root                            *
+ *             name       - [IN] name or index of the next json element       *
  *             pnext      - [IN] a pointer to object value with the specified *
  *                               name                                         *
  *             jsonpath   - [IN] the jsonpath                                 *
  *             path_depth - [IN] the jsonpath segment to match                *
  *             name       - [IN] the object value name                        *
- *             objects    - [OUT] pointers to the matched objects in json     *
- *                                data                                        *
+ *             objects    - [OUT] the matched json elements (name, value)     *
  *                                                                            *
  * Return value: SUCCEED - no errors, failed match is not an error            *
  *               FAIL    - otherwise                                          *
  *                                                                            *
  ******************************************************************************/
-static int	jsonpath_match_name(const struct zbx_json_parse *jp_root, const char *pnext,
-		const zbx_jsonpath_t *jsonpath, int path_depth, const char *name, zbx_vector_str_t *objects)
+static int	jsonpath_match_name(const struct zbx_json_parse *jp_root, const char *name, const char *pnext,
+		const zbx_jsonpath_t *jsonpath, int path_depth, zbx_vector_json_t *objects)
 {
 	zbx_jsonpath_segment_t		*segment;
 	zbx_jsonpath_list_node_t	*node;
@@ -1388,7 +1442,7 @@ static int	jsonpath_match_name(const struct zbx_json_parse *jp_root, const char
 	{
 		if (0 == strcmp(name, node->data))
 		{
-			if (FAIL == jsonpath_query_next_segment(jp_root, pnext, jsonpath, path_depth, objects))
+			if (FAIL == jsonpath_query_next_segment(jp_root, name, pnext, jsonpath, path_depth, objects))
 				return FAIL;
 			break;
 		}
@@ -1637,18 +1691,18 @@ static int	jsonpath_regexp_match(const char *text, const char *pattern, double *
  * Purpose: match json array element/object value against jsonpath expression *
  *                                                                            *
  * Parameters: jp_root    - [IN] the document root                            *
+ *             name       - [IN] name or index of the next json element       *
  *             pnext      - [IN] a pointer to array element/object value      *
  *             jsonpath   - [IN] the jsonpath                                 *
  *             path_depth - [IN] the jsonpath segment to match                *
- *             objects    - [OUT] pointers to the matched objects in json     *
- *                                data                                        *
+ *             objects    - [OUT] the matched json elements (name, value)     *
  *                                                                            *
  * Return value: SUCCEED - no errors, failed match is not an error            *
  *               FAIL    - otherwise                                          *
  *                                                                            *
  ******************************************************************************/
-static int	jsonpath_match_expression(const struct zbx_json_parse *jp_root, const char *pnext,
-		const zbx_jsonpath_t *jsonpath, int path_depth, zbx_vector_str_t *objects)
+static int	jsonpath_match_expression(const struct zbx_json_parse *jp_root, const char *name, const char *pnext,
+		const zbx_jsonpath_t *jsonpath, int path_depth, zbx_vector_json_t *objects)
 {
 	struct zbx_json_parse	jp;
 	zbx_vector_var_t	stack;
@@ -1844,7 +1898,7 @@ static int	jsonpath_match_expression(const struct zbx_json_parse *jp_root, const
 
 	jsonpath_variant_to_boolean(&stack.values[0]);
 	if (SUCCEED != zbx_double_compare(stack.values[0].data.dbl, 0.0))
-		ret = jsonpath_query_next_segment(jp_root, pnext, jsonpath, path_depth, objects);
+		ret = jsonpath_query_next_segment(jp_root, name, pnext, jsonpath, path_depth, objects);
 out:
 	for (i = 0; i < stack.values_num; i++)
 		zbx_variant_clear(&stack.values[i]);
@@ -1863,15 +1917,14 @@ out:
  *             jp         - [IN] the json object to query                     *
  *             jsonpath   - [IN] the jsonpath                                 *
  *             path_depth - [IN] the jsonpath segment to match                *
- *             objects    - [OUT] pointers to the matched objects in json     *
- *                                data                                        *
+ *             objects    - [OUT] the matched json elements (name, value)     *
  *                                                                            *
  * Return value: SUCCEED - the object was queried successfully                *
  *               FAIL    - otherwise                                          *
  *                                                                            *
  ******************************************************************************/
 static int	jsonpath_query_object(const struct zbx_json_parse *jp_root, const struct zbx_json_parse *jp,
-		const zbx_jsonpath_t *jsonpath, int path_depth, zbx_vector_str_t *objects)
+		const zbx_jsonpath_t *jsonpath, int path_depth, zbx_vector_json_t *objects)
 {
 	const char		*pnext = NULL;
 	char			name[MAX_STRING_LEN];
@@ -1885,13 +1938,13 @@ static int	jsonpath_query_object(const struct zbx_json_parse *jp_root, const str
 		switch (segment->type)
 		{
 			case ZBX_JSONPATH_SEGMENT_MATCH_ALL:
-				ret = jsonpath_query_next_segment(jp_root, pnext, jsonpath, path_depth, objects);
+				ret = jsonpath_query_next_segment(jp_root, name, pnext, jsonpath, path_depth, objects);
 				break;
 			case ZBX_JSONPATH_SEGMENT_MATCH_LIST:
-				ret = jsonpath_match_name(jp_root, pnext, jsonpath, path_depth, name, objects);
+				ret = jsonpath_match_name(jp_root, name, pnext, jsonpath, path_depth, objects);
 				break;
 			case ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION:
-				ret = jsonpath_match_expression(jp_root, pnext, jsonpath, path_depth, objects);
+				ret = jsonpath_match_expression(jp_root, name, pnext, jsonpath, path_depth, objects);
 				break;
 			default:
 				break;
@@ -1911,20 +1964,20 @@ static int	jsonpath_query_object(const struct zbx_json_parse *jp_root, const str
  * Purpose: match array element against segment index list                    *
  *                                                                            *
  * Parameters: jp_root      - [IN] the document root                          *
+ *             name         - [IN] the json element name (index)              *
  *             pnext        - [IN] a pointer to an array element              *
  *             jsonpath     - [IN] the jsonpath                               *
  *             path_depth   - [IN] the jsonpath segment to match              *
  *             index        - [IN] the array element index                    *
  *             elements_num - [IN] the total number of elements in array      *
- *             objects      - [OUT] pointers to the matched objects in json   *
- *                                  data                                      *
+ *             objects      - [OUT] the matched json elements (name, value)   *
  *                                                                            *
  * Return value: SUCCEED - no errors, failed match is not an error            *
  *               FAIL    - otherwise                                          *
  *                                                                            *
  ******************************************************************************/
-static int	jsonpath_match_index(const struct zbx_json_parse *jp_root, const char *pnext,
-		const zbx_jsonpath_t *jsonpath, int path_depth, int index, int elements_num, zbx_vector_str_t *objects)
+static int	jsonpath_match_index(const struct zbx_json_parse *jp_root, const char *name, const char *pnext,
+		const zbx_jsonpath_t *jsonpath, int path_depth, int index, int elements_num, zbx_vector_json_t *objects)
 {
 	zbx_jsonpath_segment_t		*segment;
 	zbx_jsonpath_list_node_t	*node;
@@ -1943,7 +1996,7 @@ static int	jsonpath_match_index(const struct zbx_json_parse *jp_root, const char
 
 		if ((query_index >= 0 && index == query_index) || index == elements_num + query_index)
 		{
-			if (FAIL == jsonpath_query_next_segment(jp_root, pnext, jsonpath, path_depth, objects))
+			if (FAIL == jsonpath_query_next_segment(jp_root, name, pnext, jsonpath, path_depth, objects))
 				return FAIL;
 			break;
 		}
@@ -1959,20 +2012,20 @@ static int	jsonpath_match_index(const struct zbx_json_parse *jp_root, const char
  * Purpose: match array element against segment index range                   *
  *                                                                            *
  * Parameters: jp_root      - [IN] the document root                          *
+ *             name         - [IN] the json element name (index)              *
  *             pnext        - [IN] a pointer to an array element              *
  *             jsonpath     - [IN] the jsonpath                               *
  *             path_depth   - [IN] the jsonpath segment to match              *
  *             index        - [IN] the array element index                    *
  *             elements_num - [IN] the total number of elements in array      *
- *             objects      - [OUT] pointers to the matched objects in json   *
- *                                  data                                      *
+ *             objects      - [OUT] the matched json elements (name, value)   *
  *                                                                            *
  * Return value: SUCCEED - no errors, failed match is not an error            *
  *               FAIL    - otherwise                                          *
  *                                                                            *
  ******************************************************************************/
-static int	jsonpath_match_range(const struct zbx_json_parse *jp_root, const char *pnext,
-		const zbx_jsonpath_t *jsonpath, int path_depth, int index, int elements_num, zbx_vector_str_t *objects)
+static int	jsonpath_match_range(const struct zbx_json_parse *jp_root, const char *name, const char *pnext,
+		const zbx_jsonpath_t *jsonpath, int path_depth, int index, int elements_num, zbx_vector_json_t *objects)
 {
 	int			start_index, end_index;
 	zbx_jsonpath_segment_t	*segment;
@@ -1989,7 +2042,7 @@ static int	jsonpath_match_range(const struct zbx_json_parse *jp_root, const char
 
 	if (start_index <= index && end_index > index)
 	{
-		if (FAIL == jsonpath_query_next_segment(jp_root, pnext, jsonpath, path_depth, objects))
+		if (FAIL == jsonpath_query_next_segment(jp_root, name, pnext, jsonpath, path_depth, objects))
 			return FAIL;
 	}
 
@@ -2006,15 +2059,14 @@ static int	jsonpath_match_range(const struct zbx_json_parse *jp_root, const char
  *             jp         - [IN] the json array to query                      *
  *             jsonpath   - [IN] the jsonpath                                 *
  *             path_depth - [IN] the jsonpath segment to match                *
- *             objects    - [OUT] pointers to the matched objects in json     *
- *                                data                                        *
+ *             objects    - [OUT] the matched json elements (name, value)     *
  *                                                                            *
  * Return value: SUCCEED - the array was queried successfully                 *
  *               FAIL    - otherwise                                          *
  *                                                                            *
  ******************************************************************************/
 static int	jsonpath_query_array(const struct zbx_json_parse *jp_root, const struct zbx_json_parse *jp,
-		const zbx_jsonpath_t *jsonpath, int path_depth, zbx_vector_str_t *objects)
+		const zbx_jsonpath_t *jsonpath, int path_depth, zbx_vector_json_t *objects)
 {
 	const char		*pnext = NULL;
 	int			index = 0, elements_num = 0, ret = SUCCEED;
@@ -2027,21 +2079,24 @@ static int	jsonpath_query_array(const struct zbx_json_parse *jp_root, const stru
 
 	while (NULL != (pnext = zbx_json_next(jp, pnext)) && SUCCEED == ret)
 	{
+		char	name[MAX_ID_LEN + 1];
+
+		zbx_snprintf(name, sizeof(name), "%d", index);
 		switch (segment->type)
 		{
 			case ZBX_JSONPATH_SEGMENT_MATCH_ALL:
-				ret = jsonpath_query_next_segment(jp_root, pnext, jsonpath, path_depth, objects);
+				ret = jsonpath_query_next_segment(jp_root, name, pnext, jsonpath, path_depth, objects);
 				break;
 			case ZBX_JSONPATH_SEGMENT_MATCH_LIST:
-				ret = jsonpath_match_index(jp_root, pnext, jsonpath, path_depth, index,
+				ret = jsonpath_match_index(jp_root, name, pnext, jsonpath, path_depth, index,
 						elements_num, objects);
 				break;
 			case ZBX_JSONPATH_SEGMENT_MATCH_RANGE:
-				ret = jsonpath_match_range(jp_root, pnext, jsonpath, path_depth, index,
+				ret = jsonpath_match_range(jp_root, name, pnext, jsonpath, path_depth, index,
 						elements_num, objects);
 				break;
 			case ZBX_JSONPATH_SEGMENT_MATCH_EXPRESSION:
-				ret = jsonpath_match_expression(jp_root, pnext, jsonpath, path_depth, objects);
+				ret = jsonpath_match_expression(jp_root, name, pnext, jsonpath, path_depth, objects);
 				break;
 			default:
 				break;
@@ -2122,8 +2177,7 @@ static int	jsonpath_extract_numeric_value(const char *ptr, double *value)
  *                                                                            *
  * Purpose: apply jsonpath function to the extracted object list              *
  *                                                                            *
- * Parameters: objects       - [IN] pointers to the objects/arrays/values in  *
- *                                  json data                                 *
+ * Parameters: objects       - [IN] the matched json elements (name, value)   *
  *             type          - [IN] the function type                         *
  *             definite_path - [IN] 1 - if the path is definite (pointing at  *
  *                                      single object)                        *
@@ -2135,22 +2189,53 @@ static int	jsonpath_extract_numeric_value(const char *ptr, double *value)
  *                         json error                                         *
  *                                                                            *
  ******************************************************************************/
-static int	jsonpath_apply_function(const zbx_vector_str_t *objects, zbx_jsonpath_function_type_t type,
+static int	jsonpath_apply_function(const zbx_vector_json_t *objects, zbx_jsonpath_function_type_t type,
 		int definite_path, char **output)
 {
 	int			i, ret = FAIL;
-	zbx_vector_str_t	objects_tmp;
+	zbx_vector_json_t	objects_tmp;
 	double			result;
 
-	zbx_vector_str_create(&objects_tmp);
+	zbx_vector_json_create(&objects_tmp);
+
+	if (ZBX_JSONPATH_FUNCTION_NAME == type)
+	{
+		if (0 == objects->values_num)
+		{
+			zbx_set_json_strerror("cannot extract name from empty result");
+			goto out;
+		}
+
+		/* For definite paths we have single output value, so return its name. */
+		/* Otherwise return array of all output element names.                 */
+		if (0 == definite_path)
+		{
+			struct zbx_json	j;
+
+			zbx_json_initarray(&j, 1024);
+			for (i = 0; i < objects->values_num; i++)
+				zbx_json_addstring(&j, NULL, objects->values[i].name, ZBX_JSON_TYPE_STRING);
+
+			zbx_json_close(&j);
+			*output = zbx_strdup(NULL, j.buffer);
+			zbx_json_clean(&j);
+		}
+		else
+			*output = zbx_strdup(NULL, objects->values[0].name);
+
+		ret = SUCCEED;
+		goto out;
+	}
+
 
 	/* convert definite path result to object array if possible */
 	if (0 != definite_path)
 	{
 		const char		*pnext;
 		struct zbx_json_parse	jp;
+		int			index = 0;
 
-		if (0 == objects->values_num || '[' != *objects->values[0])
+		if (0 == objects->values_num || '[' != *objects->values[0].value)
 		{
 			/* all functions can be applied only to arrays        */
 			/* attempt to apply a function to non-array will fail */
@@ -2158,11 +2243,16 @@ static int	jsonpath_apply_function(const zbx_vector_str_t *objects, zbx_jsonpath
 			goto out;
 		}
 
-		if (FAIL == zbx_json_brackets_open(objects->values[0], &jp))
+		if (FAIL == zbx_json_brackets_open(objects->values[0].value, &jp))
 			goto out;
 
 		for (pnext = NULL; NULL != (pnext = zbx_json_next(&jp, pnext));)
-			zbx_vector_str_append(&objects_tmp, (char*)pnext);
+		{
+			char	name[MAX_STRING_LEN];
+
+			zbx_snprintf(name, sizeof(name), "%d", index++);
+			zbx_vector_json_add_element(&objects_tmp, name, pnext);
+		}
 
 		objects = &objects_tmp;
 	}
@@ -2177,7 +2267,7 @@ static int	jsonpath_apply_function(const zbx_vector_str_t *objects, zbx_jsonpath
 	if (ZBX_JSONPATH_FUNCTION_FIRST == type)
 	{
 		if (0 < objects->values_num)
-			ret = jsonpath_extract_element(objects->values[0], output);
+			ret = jsonpath_extract_element(objects->values[0].value, output);
 		else
 			ret = SUCCEED;
 
@@ -2190,14 +2280,14 @@ static int	jsonpath_apply_function(const zbx_vector_str_t *objects, zbx_jsonpath
 		goto out;
 	}
 
-	if (FAIL == jsonpath_extract_numeric_value(objects->values[0], &result))
+	if (FAIL == jsonpath_extract_numeric_value(objects->values[0].value, &result))
 		goto out;
 
 	for (i = 1; i < objects->values_num; i++)
 	{
 		double	value;
 
-		if (FAIL == jsonpath_extract_numeric_value(objects->values[i], &value))
+		if (FAIL == jsonpath_extract_numeric_value(objects->values[i].value, &value))
 			goto out;
 
 		switch (type)
@@ -2231,7 +2321,8 @@ static int	jsonpath_apply_function(const zbx_vector_str_t *objects, zbx_jsonpath
 	del_zeros(*output);
 	ret = SUCCEED;
 out:
-	zbx_vector_str_destroy(&objects_tmp);
+	zbx_vector_json_clear_ext(&objects_tmp);
+	zbx_vector_json_destroy(&objects_tmp);
 
 	return ret;
 }
@@ -2243,8 +2334,7 @@ out:
  * Purpose: apply jsonpath function to the extracted object list              *
  *                                                                            *
  * Parameters: jp_root    - [IN] the document root                            *
- *             objects    - [IN] pointers to the objects/arrays/values in json*
- *                               data                                         *
+ *             objects    - [IN] the matched json elements (name, value)      *
  *             jsonpath   - [IN] the jsonpath                                 *
  *             path_depth - [IN] the jsonpath segment to match                *
  *             output     - [OUT] the output value                            *
@@ -2254,20 +2344,21 @@ out:
  *                         json error                                         *
  *                                                                            *
  ******************************************************************************/
-static int	jsonpath_apply_functions(const struct zbx_json_parse *jp_root, const zbx_vector_str_t *objects,
+static int	jsonpath_apply_functions(const struct zbx_json_parse *jp_root, const zbx_vector_json_t *objects,
 		const zbx_jsonpath_t *jsonpath, int path_depth, char **output)
 {
-	int			ret, clear_input_contents = 0, definite_path;
-	zbx_vector_str_t	input;
+	int			ret, definite_path;
+	zbx_vector_json_t	input;
+	char			*tmp_output = NULL;
 
-	zbx_vector_str_create(&input);
+	zbx_vector_json_create(&input);
 
 	/* when functions are applied directly to the json document (at the start of the jsonpath ) */
 	/* it makes all document as input object                                                    */
 	if (0 == path_depth)
-		zbx_vector_str_append(&input, (char *)jp_root->start);
+		zbx_vector_json_add_element(&input, "", jp_root->start);
 	else
-		zbx_vector_str_append_array(&input, objects->values, objects->values_num);
+		zbx_vector_json_append_array(&input, objects->values, objects->values_num);
 
 	definite_path = jsonpath->definite;
 
@@ -2277,24 +2368,25 @@ static int	jsonpath_apply_functions(const struct zbx_json_parse *jp_root, const
 		if (++path_depth == jsonpath->segments_num)
 			break;
 
-		if (0 != clear_input_contents)
-			zbx_vector_str_clear_ext(&input, zbx_str_free);
-		else
-			zbx_vector_str_clear(&input);
+		zbx_vector_json_clear_ext(&input);
 
 		if (NULL != *output)
-			zbx_vector_str_append(&input, *output);
+		{
+			zbx_vector_json_add_element(&input, "", *output);
+			zbx_free(tmp_output);
+			tmp_output = *output;
+		}
 
 		*output = NULL;
-		clear_input_contents = 1;
+
 
 		/* functions return single value, so for the next functions path becomes definite */
 		definite_path = 1;
 	}
 
-	if (0 != clear_input_contents)
-		zbx_vector_str_clear_ext(&input, zbx_str_free);
-	zbx_vector_str_destroy(&input);
+	zbx_free(tmp_output);
+	zbx_vector_json_clear_ext(&input);
+	zbx_vector_json_destroy(&input);
 
 	return ret;
 }
@@ -2305,8 +2397,7 @@ static int	jsonpath_apply_functions(const struct zbx_json_parse *jp_root, const
  *                                                                            *
  * Purpose: format query result, depending on jsonpath type                   *
  *                                                                            *
- * Parameters: objects  - [IN] pointers to the objects/arrays/values in json  *
- *                             data                                           *
+ * Parameters: objects  - [IN] the matched json elements (name, value)        *
  *             jsonpath - [IN] the jsonpath used to acquire result            *
  *             output   - [OUT] the output value                              *
  *                                                                            *
@@ -2314,7 +2405,7 @@ static int	jsonpath_apply_functions(const struct zbx_json_parse *jp_root, const
  *               FAIL    - invalid result data (internal json error)          *
  *                                                                            *
  ******************************************************************************/
-static int	jsonpath_format_query_result(const zbx_vector_str_t *objects, zbx_jsonpath_t *jsonpath, char **output)
+static int	jsonpath_format_query_result(const zbx_vector_json_t *objects, zbx_jsonpath_t *jsonpath, char **output)
 {
 	size_t	output_offset = 0, output_alloc;
 	int	i;
@@ -2324,7 +2415,7 @@ static int	jsonpath_format_query_result(const zbx_vector_str_t *objects, zbx_jso
 
 	if (1 == jsonpath->definite)
 	{
-		return jsonpath_extract_element(objects->values[0], output);
+		return jsonpath_extract_element(objects->values[0].value, output);
 	}
 
 	/* reserve 32 bytes per returned object plus array start/end [] and terminating zero */
@@ -2337,10 +2428,10 @@ static int	jsonpath_format_query_result(const zbx_vector_str_t *objects, zbx_jso
 	{
 		struct zbx_json_parse	jp;
 
-		if (FAIL == jsonpath_pointer_to_jp(objects->values[i], &jp))
+		if (FAIL == jsonpath_pointer_to_jp(objects->values[i].value, &jp))
 		{
 			zbx_set_json_strerror("cannot format query result, unrecognized json part starting with: %s",
-					objects->values[i]);
+					objects->values[i].value);
 			zbx_free(*output);
 			return FAIL;
 		}
@@ -2442,6 +2533,9 @@ int	zbx_jsonpath_compile(const char *path, zbx_jsonpath_t *jsonpath)
 			case '[':
 				ret = jsonpath_parse_bracket_segment(ptr + 1, &jpquery, &next);
 				break;
+			case '~':
+				ret = jsonpath_parse_name_reference(&jpquery, &next);
+				break;
 			default:
 				ret = zbx_jsonpath_error(ptr);
 				break;
@@ -2490,12 +2584,12 @@ int	zbx_jsonpath_query(const struct zbx_json_parse *jp, const char *path, char *
 {
 	zbx_jsonpath_t		jsonpath;
 	int			path_depth = 0, ret = SUCCEED;
-	zbx_vector_str_t	objects;
+	zbx_vector_json_t	objects;
 
 	if (FAIL == zbx_jsonpath_compile(path, &jsonpath))
 		return FAIL;
 
-	zbx_vector_str_create(&objects);
+	zbx_vector_json_create(&objects);
 
 	if ('{' == *jp->start)
 		ret = jsonpath_query_object(jp, jp, &jsonpath, path_depth, &objects);
@@ -2514,8 +2608,45 @@ int	zbx_jsonpath_query(const struct zbx_json_parse *jp, const char *path, char *
 			ret = jsonpath_format_query_result(&objects, &jsonpath, output);
 	}
 
-	zbx_vector_str_destroy(&objects);
+	zbx_vector_json_destroy(&objects);
 	zbx_jsonpath_clear(&jsonpath);
 
 	return ret;
 }
+
+// WDN
+
+static void	test_jsonpath(const char *input, const char *path)
+{
+	struct zbx_json_parse	jp;
+	char			*output = NULL;
+
+	if (FAIL == zbx_json_open(input, &jp))
+	{
+		printf("invalid json: %s\n", zbx_json_strerror());
+		return;
+	}
+
+
+	if (FAIL == zbx_jsonpath_query(&jp, path, &output))
+	{
+		printf("FAIL: %s\n", zbx_json_strerror());
+	}
+	else
+	{
+		printf("OK: %s\n", output);
+		zbx_free(output);
+	}
+}
+
+
+void	test()
+{
+	test_jsonpath("{\"a\":1, \"b\":1}", "$.*~");
+	test_jsonpath("[\"a\", \"b\"]", "$.*~");
+	test_jsonpath("{\"a\":1, \"b\":1}", "$.*~.first()");
+	test_jsonpath("[\"a\", \"b\"]", "$[0]~");
+
+	exit(0);
+}
+
diff --git a/src/libs/zbxjson/jsonpath.h b/src/libs/zbxjson/jsonpath.h
index 3c5b257d11..0543a351db 100644
--- a/src/libs/zbxjson/jsonpath.h
+++ b/src/libs/zbxjson/jsonpath.h
@@ -48,7 +48,8 @@ typedef enum
 	ZBX_JSONPATH_FUNCTION_AVG,
 	ZBX_JSONPATH_FUNCTION_LENGTH,
 	ZBX_JSONPATH_FUNCTION_FIRST,
-	ZBX_JSONPATH_FUNCTION_SUM
+	ZBX_JSONPATH_FUNCTION_SUM,
+	ZBX_JSONPATH_FUNCTION_NAME,
 }
 zbx_jsonpath_function_type_t;
 
diff --git a/src/zabbix_server/server.c b/src/zabbix_server/server.c
index 496f141744..74d620f645 100644
--- a/src/zabbix_server/server.c
+++ b/src/zabbix_server/server.c
@@ -809,6 +809,13 @@ int	main(int argc, char **argv)
 	char		ch, *error = NULL;
 	int		opt_c = 0, opt_r = 0;
 
+	// WDN
+	{
+		test();
+	}
+
+
+
 #if defined(PS_OVERWRITE_ARGV) || defined(PS_PSTAT_ARGV)
 	argv = setproctitle_save_env(argc, argv);
 #endif
