data tree FEATURE option to skip list key children
diff --git a/src/path.c b/src/path.c
index bcbfe01..23e0cfb 100644
--- a/src/path.c
+++ b/src/path.c
@@ -772,7 +772,7 @@
 
     if (lysc_data_parent(path[0].node)) {
         /* relative path, start from the parent children */
-        start = lyd_node_children(start);
+        start = lyd_node_children(start, 0);
     } else {
         /* absolute path, start from the first top-level sibling */
         while (start->parent) {
@@ -823,7 +823,7 @@
         prev_node = node;
 
         /* next path segment, if any */
-        start = lyd_node_children(node);
+        start = lyd_node_children(node, 0);
     }
 
     if (node) {
diff --git a/src/tree_data.c b/src/tree_data.c
index f55f10c..fc08039 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -1340,18 +1340,18 @@
     if (parent) {
         if (node->schema && (node->schema->flags & LYS_KEY)) {
             /* it is key and we need to insert it at the correct place */
-            anchor = lyd_get_prev_key_anchor(lyd_node_children(parent), node->schema);
+            anchor = lyd_get_prev_key_anchor(lyd_node_children(parent, 0), node->schema);
             if (anchor) {
                 lyd_insert_after_node(anchor, node);
-            } else if (lyd_node_children(parent)) {
-                lyd_insert_before_node(lyd_node_children(parent), node);
+            } else if (lyd_node_children(parent, 0)) {
+                lyd_insert_before_node(lyd_node_children(parent, 0), node);
             } else {
                 lyd_insert_last_node(parent, node);
             }
 
             /* hash list if all its keys were added */
             assert(parent->schema->nodetype == LYS_LIST);
-            anchor = lyd_node_children(parent);
+            anchor = lyd_node_children(parent, 0);
             has_keys = 1;
             while ((skey = lys_getnext(skey, parent->schema, NULL, 0)) && (skey->flags & LYS_KEY)) {
                 if (!anchor || (anchor->schema != skey)) {
@@ -2269,12 +2269,7 @@
             lyd_free_tree(dup_src);
         } else {
             /* check descendants, recursively */
-            LY_LIST_FOR_SAFE(lyd_node_children(sibling_src), tmp, child_src) {
-                if ((child_src->schema->nodetype == LYS_LEAF) && (child_src->schema->flags & LYS_KEY)) {
-                    /* skip keys */
-                    continue;
-                }
-
+            LY_LIST_FOR_SAFE(LYD_CHILD(sibling_src), tmp, child_src) {
                 LY_CHECK_RET(lyd_merge_sibling_r(lyd_node_children_p(match_trg), match_trg, &child_src, options));
             }
         }
@@ -2383,7 +2378,7 @@
     char quot;
     LY_ERR rc;
 
-    for (key = lyd_node_children(node); key && (key->schema->flags & LYS_KEY); key = key->next) {
+    for (key = lyd_node_children(node, 0); key && (key->schema->flags & LYS_KEY); key = key->next) {
         val = lyd_value2str((struct lyd_node_term *)key, &dynamic);
         len = 1 + strlen(key->schema->name) + 2 + strlen(val) + 2;
         rc = lyd_path_str_enlarge(buffer, buflen, *bufused + len, is_static);
@@ -2626,7 +2621,7 @@
             /* compare all set keys */
             LY_ARRAY_FOR(predicates, u) {
                 /* find key */
-                rc = lyd_find_sibling_val(lyd_node_children(node), predicates[u].key, NULL, 0, (struct lyd_node **)&term);
+                rc = lyd_find_sibling_val(lyd_node_children(node, 0), predicates[u].key, NULL, 0, (struct lyd_node **)&term);
                 if (rc == LY_ENOTFOUND) {
                     /* all keys must always exist */
                     LOGINT_RET(schema->module->ctx);
diff --git a/src/tree_data.h b/src/tree_data.h
index 1c4e9c0..235062d 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -88,7 +88,7 @@
 
 #define LYD_TREE_DFS_END(START, NEXT, ELEM) \
     /* select element for the next run - children first */ \
-    (NEXT) = lyd_node_children((struct lyd_node*)ELEM); \
+    (NEXT) = lyd_node_children((struct lyd_node*)ELEM, 0); \
     if (!(NEXT)) { \
         /* no children */ \
         if ((ELEM) == (struct lyd_node*)(START)) { \
@@ -517,13 +517,23 @@
 //#define LYD_OPT_DATA_TEMPLATE 0x1000000 /**< Data represents YANG data template. */
 
 /**
+ * @defgroup children_options Children traversal options.
+ * @ingroup datatree
+ */
+
+#define LYD_CHILDREN_SKIP_KEYS  0x01    /**< If list children are returned, skip its keys. */
+
+/** @} children_options */
+
+/**
  * @brief Get the node's children list if any.
  *
  * Decides the node's type and in case it has a children list, returns it.
  * @param[in] node Node to check.
+ * @param[in] options Bitmask of options, see @ref
  * @return Pointer to the first child node (if any) of the \p node.
  */
-struct lyd_node *lyd_node_children(const struct lyd_node *node);
+struct lyd_node *lyd_node_children(const struct lyd_node *node, int options);
 
 /**
  * @brief Get the owner module of the data node. It is the module of the top-level schema node. Generally,
diff --git a/src/tree_data_free.c b/src/tree_data_free.c
index 7975b87..43bafee 100644
--- a/src/tree_data_free.c
+++ b/src/tree_data_free.c
@@ -136,7 +136,7 @@
         opaq = (struct lyd_node_opaq *)node;
 
         /* free the children */
-        children = lyd_node_children(node);
+        children = lyd_node_children(node, 0);
         LY_LIST_FOR_SAFE(children, next, iter) {
             lyd_free_subtree(iter, 0);
         }
@@ -158,7 +158,7 @@
         ((struct lyd_node_inner *)node)->children_ht = NULL;
 
         /* free the children */
-        children = lyd_node_children(node);
+        children = lyd_node_children(node, 0);
         LY_LIST_FOR_SAFE(children, next, iter) {
             lyd_free_subtree(iter, 0);
         }
diff --git a/src/tree_data_helpers.c b/src/tree_data_helpers.c
index 798f238..4e85ebe 100644
--- a/src/tree_data_helpers.c
+++ b/src/tree_data_helpers.c
@@ -45,17 +45,23 @@
 }
 
 API struct lyd_node *
-lyd_node_children(const struct lyd_node *node)
+lyd_node_children(const struct lyd_node *node, int options)
 {
-    struct lyd_node **children;
+    struct lyd_node **children, *child;
 
     if (!node) {
         return NULL;
     }
 
-    children = lyd_node_children_p((struct lyd_node*)node);
+    children = lyd_node_children_p((struct lyd_node *)node);
     if (children) {
-        return *children;
+        child = *children;
+        if (options & LYD_CHILDREN_SKIP_KEYS) {
+            while (child && (child->schema->flags & LYS_KEY)) {
+                child = child->next;
+            }
+        }
+        return child;
     } else {
         return NULL;
     }
@@ -140,7 +146,7 @@
 
     assert(node->schema->nodetype == LYS_LIST);
 
-    key = lyd_node_children(node);
+    key = lyd_node_children(node, 0);
     while ((skey = lys_getnext(skey, node->schema, NULL, 0)) && (skey->flags & LYS_KEY)) {
         if (!key || (key->schema != skey)) {
             LOGVAL(node->schema->module->ctx, LY_VLOG_LYD, node, LY_VCODE_NOKEY, skey->name);
diff --git a/src/tree_data_internal.h b/src/tree_data_internal.h
index 6596aa8..439ad6c 100644
--- a/src/tree_data_internal.h
+++ b/src/tree_data_internal.h
@@ -31,6 +31,14 @@
 #define LYD_DEL_IS_ROOT(first, to_del) (((first) == (to_del)) && !(first)->parent && !(first)->prev->next)
 
 /**
+ * @brief Shorthand for getting data children without its keys.
+ *
+ * @param[in] node Node, whose children to traverse.
+ * @return Node children, skipping any keys of a list.
+ */
+#define LYD_CHILD(node) lyd_node_children(node, LYD_CHILDREN_SKIP_KEYS)
+
+/**
  * @brief Get address of a node's child pointer if any.
  *
  * @param[in] node Node to check.
diff --git a/src/validation.c b/src/validation.c
index 1219d89..22919f0 100644
--- a/src/validation.c
+++ b/src/validation.c
@@ -518,7 +518,7 @@
 
         /* find iter instance in children */
         assert(iter->nodetype & (LYS_CONTAINER | LYS_LEAF));
-        lyd_find_sibling_val(lyd_node_children(node), iter, NULL, 0, &node);
+        lyd_find_sibling_val(lyd_node_children(node, 0), iter, NULL, 0, &node);
         --depth;
     }
 
@@ -922,11 +922,11 @@
 
     LY_LIST_FOR(first, node) {
         /* validate all children recursively */
-        LY_CHECK_RET(lyd_validate_final_r(lyd_node_children(node), node->schema, NULL, val_opts));
+        LY_CHECK_RET(lyd_validate_final_r(lyd_node_children(node, 0), node->schema, NULL, val_opts));
 
         /* set default for containers */
         if ((node->schema->nodetype == LYS_CONTAINER) && !(node->schema->flags & LYS_PRESENCE)) {
-            LY_LIST_FOR(lyd_node_children(node), next) {
+            LY_LIST_FOR(lyd_node_children(node, 0), next) {
                 if (!(next->flags & LYD_DEFAULT)) {
                     break;
                 }
@@ -1178,7 +1178,7 @@
         }
 
         /* move tree_iter */
-        tree_iter = lyd_node_children(match);
+        tree_iter = lyd_node_children(match, 0);
 
         /* move depth */
         --cur_depth;
@@ -1250,7 +1250,7 @@
     LY_CHECK_GOTO(ret = lyd_validate_must(op, val_opts), cleanup);
 
     /* final validation of all the descendants */
-    LY_CHECK_GOTO(ret = lyd_validate_final_r(lyd_node_children(op), op->schema, NULL, val_opts), cleanup);
+    LY_CHECK_GOTO(ret = lyd_validate_final_r(lyd_node_children(op, 0), op->schema, NULL, val_opts), cleanup);
 
 cleanup:
     /* restore operation tree */
diff --git a/src/xpath.c b/src/xpath.c
index 39c7365..1a13f1f 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -192,7 +192,7 @@
                         && (((struct lyd_node_inner *)item->node)->child->schema->nodetype == LYS_LEAF)) {
                     LOGDBG(LY_LDGXPATH, "\t%d (pos %u): ELEM %s (1st child val: %s)", i + 1, item->pos,
                            item->node->schema->name,
-                           (str = (char *)lyd_value2str((struct lyd_node_term *)lyd_node_children(item->node), &dynamic)));
+                           (str = (char *)lyd_value2str((struct lyd_node_term *)lyd_node_children(item->node, 0), &dynamic)));
                     if (dynamic) {
                         free(str);
                     }
@@ -362,7 +362,7 @@
         strcpy(*str + (*used - 1), "\n");
         ++(*used);
 
-        for (child = lyd_node_children(node); child; child = child->next) {
+        for (child = lyd_node_children(node, 0); child; child = child->next) {
             rc = cast_string_recursive(child, 0, root_type, indent + 1, str, used, size);
             LY_CHECK_RET(rc);
         }
@@ -1322,7 +1322,7 @@
             if (elem->schema->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_ANYDATA)) {
                 next = NULL;
             } else {
-                next = lyd_node_children(elem);
+                next = lyd_node_children(elem, 0);
             }
             if (!next) {
 skip_children:
@@ -5437,16 +5437,15 @@
 
     for (i = 0; i < set->used; ) {
         replaced = 0;
-        siblings = NULL;
 
         if ((set->val.nodes[i].type == LYXP_NODE_ROOT_CONFIG) || (set->val.nodes[i].type == LYXP_NODE_ROOT)) {
             assert(!set->val.nodes[i].node);
 
             /* search in all the trees */
             siblings = set->tree;
-        } else if (!(set->val.nodes[i].node->schema->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_ANYDATA))) {
+        } else {
             /* search in children */
-            siblings = lyd_node_children(set->val.nodes[i].node);
+            siblings = lyd_node_children(set->val.nodes[i].node, 0);
         }
 
         for (sub = siblings; sub; sub = sub->next) {
@@ -5527,7 +5526,7 @@
             siblings = set->tree;
         } else if (set->val.nodes[i].type == LYXP_NODE_ELEM) {
             /* search in children */
-            siblings = lyd_node_children(set->val.nodes[i].node);
+            siblings = lyd_node_children(set->val.nodes[i].node, 0);
         }
 
         /* find the node using hashes */
@@ -5716,7 +5715,7 @@
 
             /* TREE DFS NEXT ELEM */
             /* select element for the next run - children first */
-            next = lyd_node_children(elem);
+            next = lyd_node_children(elem, 0);
             if (!next) {
 skip_children:
                 /* no children, so try siblings, but only if it's not the start,
@@ -6063,7 +6062,7 @@
         }
 
         /* add all the children of this node */
-        first = lyd_node_children(parent);
+        first = lyd_node_children(parent, 0);
         break;
     default:
         LOGINT_RET(parent->schema->module->ctx);