data tree REFACTOR data DFS should match schema DFS
diff --git a/src/diff.c b/src/diff.c
index a4c1f06..251d259 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -1656,7 +1656,7 @@
 {
     LY_ERR ret = LY_SUCCESS;
     const struct lys_module *mod;
-    struct lyd_node *root, *next, *elem;
+    struct lyd_node *root, *elem;
     enum lyd_diff_op op;
 
     LY_CHECK_ARG_RET(NULL, diff, LY_EINVAL);
@@ -1674,7 +1674,7 @@
     LY_CHECK_ERR_GOTO(!mod, LOGINT(LYD_NODE_CTX(src_diff)); ret = LY_EINT, cleanup);
 
     LY_LIST_FOR(*diff, root) {
-        LYD_TREE_DFS_BEGIN(root, next, elem) {
+        LYD_TREE_DFS_BEGIN(root, elem) {
             /* find operation attribute, if any */
             LY_CHECK_GOTO(ret = lyd_diff_get_op(elem, &op), cleanup);
 
@@ -1726,7 +1726,7 @@
                 break;
             }
 
-            LYD_TREE_DFS_END(root, next, elem);
+            LYD_TREE_DFS_END(root, elem);
         }
     }
 
diff --git a/src/parser_lyb.c b/src/parser_lyb.c
index 65fdb19..fc74236 100644
--- a/src/parser_lyb.c
+++ b/src/parser_lyb.c
@@ -1199,11 +1199,11 @@
     }
 
     /* find request OP */
-    LYD_TREE_DFS_BEGIN((struct lyd_node *)request, iter, req_op) {
+    LYD_TREE_DFS_BEGIN((struct lyd_node *)request, req_op) {
         if (req_op->schema->nodetype & (LYS_RPC | LYS_ACTION)) {
             break;
         }
-        LYD_TREE_DFS_END(request, iter, req_op);
+        LYD_TREE_DFS_END(request, req_op);
     }
     if (!(req_op->schema->nodetype & (LYS_RPC | LYS_ACTION))) {
         LOGERR(LYD_NODE_CTX(request), LY_EINVAL, "No RPC/action in the request found.");
diff --git a/src/parser_xml.c b/src/parser_xml.c
index bc8b7e7..a3c8acf 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -1071,11 +1071,11 @@
     }
 
     /* find request OP */
-    LYD_TREE_DFS_BEGIN((struct lyd_node *)request, iter, req_op) {
+    LYD_TREE_DFS_BEGIN((struct lyd_node *)request, req_op) {
         if (req_op->schema->nodetype & (LYS_RPC | LYS_ACTION)) {
             break;
         }
-        LYD_TREE_DFS_END(request, iter, req_op);
+        LYD_TREE_DFS_END(request, req_op);
     }
     if (!(req_op->schema->nodetype & (LYS_RPC | LYS_ACTION))) {
         LOGERR(LYD_NODE_CTX(request), LY_EINVAL, "No RPC/action in the request found.");
diff --git a/src/printer.c b/src/printer.c
index 0e89500..2fcd436 100644
--- a/src/printer.c
+++ b/src/printer.c
@@ -112,7 +112,7 @@
 int
 ly_should_print(const struct lyd_node *node, int options)
 {
-    const struct lyd_node *next, *elem;
+    const struct lyd_node *elem;
 
     if (options & LYD_PRINT_WD_TRIM) {
         /* do not print default nodes */
@@ -128,23 +128,23 @@
     } else if ((node->flags & LYD_DEFAULT) && !(options & LYD_PRINT_WD_MASK) && !(node->schema->flags & LYS_CONFIG_R)) {
         /* LYDP_WD_EXPLICIT
          * - print only if it contains status data in its subtree */
-        LYD_TREE_DFS_BEGIN(node, next, elem) {
+        LYD_TREE_DFS_BEGIN(node, elem) {
             if ((elem->schema->nodetype != LYS_CONTAINER) || (elem->schema->flags & LYS_PRESENCE)) {
                 if (elem->schema->flags & LYS_CONFIG_R) {
                     return 1;
                 }
             }
-            LYD_TREE_DFS_END(node, next, elem)
+            LYD_TREE_DFS_END(node, elem)
         }
         return 0;
     } else if ((node->flags & LYD_DEFAULT) && (node->schema->nodetype == LYS_CONTAINER) && !(options & LYD_PRINT_KEEPEMPTYCONT)) {
         /* avoid empty default containers */
-        LYD_TREE_DFS_BEGIN(node, next, elem) {
+        LYD_TREE_DFS_BEGIN(node, elem) {
             if (elem->schema->nodetype != LYS_CONTAINER) {
                 return 1;
             }
             assert(elem->flags & LYD_DEFAULT);
-            LYD_TREE_DFS_END(node, next, elem)
+            LYD_TREE_DFS_END(node, elem)
         }
         return 0;
     }
diff --git a/src/tree_data.c b/src/tree_data.c
index 69852d0..8bfaaa3 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -1439,7 +1439,7 @@
 API LY_ERR
 lyd_new_implicit_tree(struct lyd_node *tree, int implicit_options, struct lyd_node **diff)
 {
-    struct lyd_node *next, *node;
+    struct lyd_node *node;
     LY_ERR ret = LY_SUCCESS;
 
     LY_CHECK_ARG_RET(NULL, tree, LY_EINVAL);
@@ -1447,7 +1447,7 @@
         *diff = NULL;
     }
 
-    LYD_TREE_DFS_BEGIN(tree, next, node) {
+    LYD_TREE_DFS_BEGIN(tree, node) {
         /* skip added default nodes */
         if (((node->flags & (LYD_DEFAULT | LYD_NEW)) != (LYD_DEFAULT | LYD_NEW))
                 && (node->schema->nodetype & LYD_NODE_INNER)) {
@@ -1455,7 +1455,7 @@
                                                    NULL, implicit_options, diff), cleanup);
         }
 
-        LYD_TREE_DFS_END(tree, next, node);
+        LYD_TREE_DFS_END(tree, node);
     }
 
 cleanup:
@@ -2667,7 +2667,7 @@
 {
     LY_ERR ret;
     const struct lyd_node *child_src, *tmp, *sibling_src;
-    struct lyd_node *match_trg, *dup_src, *next, *elem;
+    struct lyd_node *match_trg, *dup_src, *elem;
     struct lysc_type *type;
 
     sibling_src = *sibling_src_p;
@@ -2720,9 +2720,9 @@
         }
 
         /* set LYD_NEW for all the new nodes, required for validation */
-        LYD_TREE_DFS_BEGIN(dup_src, next, elem) {
+        LYD_TREE_DFS_BEGIN(dup_src, elem) {
             elem->flags |= LYD_NEW;
-            LYD_TREE_DFS_END(dup_src, next, elem);
+            LYD_TREE_DFS_END(dup_src, elem);
         }
 
         lyd_insert_node(parent_trg, first_trg, dup_src);
diff --git a/src/tree_data.h b/src/tree_data.h
index bb33b43..24ab7e7 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -54,51 +54,54 @@
  * </pre>
  *
  * Use the same parameters for #LYD_TREE_DFS_BEGIN and #LYD_TREE_DFS_END. While
- * START can be any of the lyd_node* types, NEXT and ELEM variables are expected
- * to be pointers to a generic struct lyd_node.
+ * START can be any of the lyd_node* types, ELEM variable must be a pointer to
+ * the generic struct lyd_node.
  *
- * Since the next node is selected as part of #LYD_TREE_DFS_END, do not use
- * continue statement between the #LYD_TREE_DFS_BEGIN and #LYD_TREE_DFS_END.
+ * To skip a particular subtree, instead of the continue statement, set LYD_TREE_DFS_continue
+ * variable to non-zero value.
  *
  * Use with opening curly bracket '{' after the macro.
  *
  * @param START Pointer to the starting element processed first.
- * @param NEXT Temporary storage, do not use.
  * @param ELEM Iterator intended for use in the block.
  */
-#define LYD_TREE_DFS_BEGIN(START, NEXT, ELEM) \
-    for ((ELEM) = (NEXT) = (START); \
+#define LYD_TREE_DFS_BEGIN(START, ELEM) \
+    { int LYD_TREE_DFS_continue = 0; struct lyd_node *LYD_TREE_DFS_next; \
+    for ((ELEM) = (LYD_TREE_DFS_next) = (struct lyd_node *)(START); \
          (ELEM); \
-         (ELEM) = (NEXT))
+         (ELEM) = (LYD_TREE_DFS_next), LYD_TREE_DFS_continue = 0)
 
 /**
  * @brief Macro to iterate via all elements in a tree. This is the closing part
  * to the #LYD_TREE_DFS_BEGIN - they always have to be used together.
  *
  * Use the same parameters for #LYD_TREE_DFS_BEGIN and #LYD_TREE_DFS_END. While
- * START can be any of the lyd_node* types, NEXT and ELEM variables are expected
- * to be pointers to a generic struct lyd_node.
+ * START can be any of the lyd_node* types, ELEM variable must be a pointer
+ * to the generic struct lyd_node.
  *
  * Use with closing curly bracket '}' after the macro.
  *
  * @param START Pointer to the starting element processed first.
- * @param NEXT Temporary storage, do not use.
  * @param ELEM Iterator intended for use in the block.
  */
 
-#define LYD_TREE_DFS_END(START, NEXT, ELEM) \
+#define LYD_TREE_DFS_END(START, ELEM) \
     /* select element for the next run - children first */ \
-    (NEXT) = lyd_node_children((struct lyd_node*)ELEM, 0); \
-    if (!(NEXT)) { \
+    if (LYD_TREE_DFS_continue) { \
+        (LYD_TREE_DFS_next) = NULL; \
+    } else { \
+        (LYD_TREE_DFS_next) = lyd_node_children(ELEM, 0); \
+    }\
+    if (!(LYD_TREE_DFS_next)) { \
         /* no children */ \
         if ((ELEM) == (struct lyd_node*)(START)) { \
             /* we are done, (START) has no children */ \
             break; \
         } \
         /* try siblings */ \
-        (NEXT) = (ELEM)->next; \
+        (LYD_TREE_DFS_next) = (ELEM)->next; \
     } \
-    while (!(NEXT)) { \
+    while (!(LYD_TREE_DFS_next)) { \
         /* parent is already processed, go to its sibling */ \
         (ELEM) = (struct lyd_node*)(ELEM)->parent; \
         /* no siblings, go back through parents */ \
@@ -106,8 +109,8 @@
             /* we are done, no next element to process */ \
             break; \
         } \
-        (NEXT) = (ELEM)->next; \
-    }
+        (LYD_TREE_DFS_next) = (ELEM)->next; \
+    } } \
 
 /**
  * @brief Macro to get context from a data tree node.
diff --git a/src/validation.c b/src/validation.c
index 9f556f2..9c39173 100644
--- a/src/validation.c
+++ b/src/validation.c
@@ -1028,9 +1028,9 @@
                      struct ly_set *when_check, int val_opts, struct lyd_node **diff)
 {
     const struct lyd_meta *meta;
-    struct lyd_node *next, *node;
+    struct lyd_node *node;
 
-    LYD_TREE_DFS_BEGIN(root, next, node) {
+    LYD_TREE_DFS_BEGIN(root, node) {
         /* skip added default nodes */
         if ((node->flags & (LYD_DEFAULT | LYD_NEW)) != (LYD_DEFAULT | LYD_NEW)) {
             LY_LIST_FOR(node->meta, meta) {
@@ -1057,7 +1057,7 @@
             }
         }
 
-        LYD_TREE_DFS_END(root, next, node);
+        LYD_TREE_DFS_END(root, node);
     }
 
     return LY_SUCCESS;
@@ -1205,7 +1205,7 @@
 lyd_validate_op(struct lyd_node *op_tree, const struct lyd_node *tree, LYD_VALIDATE_OP op, struct lyd_node **diff)
 {
     LY_ERR ret;
-    struct lyd_node *tree_sibling, *op_subtree, *op_next, *op_node, *op_parent;
+    struct lyd_node *tree_sibling, *op_subtree, *op_node, *op_parent;
     struct ly_set type_check = {0}, type_meta_check = {0}, when_check = {0};
 
     LY_CHECK_ARG_RET(NULL, op_tree, !op_tree->parent, !tree || !tree->parent,
@@ -1215,13 +1215,13 @@
     }
 
     /* find the operation/notification */
-    LYD_TREE_DFS_BEGIN(op_tree, op_next, op_node) {
+    LYD_TREE_DFS_BEGIN(op_tree, op_node) {
         if ((op == LYD_VALIDATE_OP_RPC || op == LYD_VALIDATE_OP_REPLY) && (op_node->schema->nodetype & (LYS_RPC | LYS_ACTION))) {
             break;
         } else if ((op == LYD_VALIDATE_OP_NOTIF) && (op_node->schema->nodetype == LYS_NOTIF)) {
             break;
         }
-        LYD_TREE_DFS_END(op_tree, op_next, op_node);
+        LYD_TREE_DFS_END(op_tree, op_node);
     }
     if (op == LYD_VALIDATE_OP_RPC || op == LYD_VALIDATE_OP_REPLY) {
         if (!(op_node->schema->nodetype & (LYS_RPC | LYS_ACTION))) {
diff --git a/src/xpath.c b/src/xpath.c
index c104dd3..61edb2d 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -1301,7 +1301,7 @@
 get_node_pos(const struct lyd_node *node, enum lyxp_node_type node_type, const struct lyd_node *root,
              enum lyxp_node_type root_type, const struct lyd_node **prev, uint32_t *prev_pos)
 {
-    const struct lyd_node *next, *elem = NULL, *top_sibling;
+    const struct lyd_node *elem = NULL, *top_sibling;
     uint32_t pos = 1;
 
     assert(prev && prev_pos && !root->prev->next);
@@ -1312,55 +1312,31 @@
 
     if (*prev) {
         /* start from the previous element instead from the root */
-        elem = next = *prev;
         pos = *prev_pos;
-        for (top_sibling = elem; top_sibling->parent; top_sibling = (struct lyd_node *)top_sibling->parent);
+        for (top_sibling = *prev; top_sibling->parent; top_sibling = (struct lyd_node *)top_sibling->parent);
         goto dfs_search;
     }
 
     for (top_sibling = root; top_sibling; top_sibling = top_sibling->next) {
-        /* TREE DFS */
-        LYD_TREE_DFS_BEGIN(top_sibling, next, elem) {
+        LYD_TREE_DFS_BEGIN(top_sibling, elem) {
 dfs_search:
+            if (*prev && !elem) {
+                /* resume previous DFS */
+                elem = LYD_TREE_DFS_next = (struct lyd_node *)*prev;
+                LYD_TREE_DFS_continue = 0;
+            }
+
             if ((root_type == LYXP_NODE_ROOT_CONFIG) && (elem->schema->flags & LYS_CONFIG_R)) {
-                goto skip_children;
-            }
-
-            if (elem == node) {
-                break;
-            }
-            ++pos;
-
-            /* TREE DFS END */
-            /* select element for the next run - children first,
-             * child exception for lyd_node_leaf and lyd_node_leaflist, but not the root */
-            if (elem->schema->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_ANYDATA)) {
-                next = NULL;
+                /* skip */
+                LYD_TREE_DFS_continue = 1;
             } else {
-                next = lyd_node_children(elem, 0);
-            }
-            if (!next) {
-skip_children:
-                /* no children */
-                if (elem == top_sibling) {
-                    /* we are done, root has no children */
-                    elem = NULL;
+                if (elem == node) {
                     break;
                 }
-                /* try siblings */
-                next = elem->next;
+                ++pos;
             }
-            while (!next) {
-                /* no siblings, go back through parents */
-                if (elem->parent == top_sibling->parent) {
-                    /* we are done, no next element to process */
-                    elem = NULL;
-                    break;
-                }
-                /* parent is already processed, go to its sibling */
-                elem = (struct lyd_node *)elem->parent;
-                next = elem->next;
-            }
+
+            LYD_TREE_DFS_END(top_sibling, elem);
         }
 
         /* node found */
@@ -1372,13 +1348,13 @@
     if (!elem) {
         if (!(*prev)) {
             /* we went from root and failed to find it, cannot be */
-            LOGINT(node->schema->module->ctx);
+            LOGINT(LYD_NODE_CTX(node));
             return 0;
         } else {
-            *prev = NULL;
-            *prev_pos = 0;
+            /* start the search again from the beginning */
+            *prev = root;
 
-            elem = next = top_sibling = root;
+            top_sibling = root;
             pos = 1;
             goto dfs_search;
         }
diff --git a/tests/utests/data/test_lyb.c b/tests/utests/data/test_lyb.c
index 2a509d3..ebb69cb 100644
--- a/tests/utests/data/test_lyb.c
+++ b/tests/utests/data/test_lyb.c
@@ -38,10 +38,33 @@
     }
 
 loop_begin:
-    LYD_TREE_DFS_BEGIN(*start, *next, *elem) {
+    /* LYD_TREE_DFS_BEGIN */
+    for (*elem = *next = *start; *elem; *elem = *next) {
         return;
 loop_next:
-        LYD_TREE_DFS_END(*start, *next, *elem);
+        /* LYD_TREE_DFS_END */
+
+        /* select element for the next run - children first */
+        *next = lyd_node_children(*elem, 0);
+        if (!*next) {
+            /* no children */
+            if (*elem == *start) {
+                /* we are done, (START) has no children */
+                break;
+            }
+            /* try siblings */
+            *next = (*elem)->next;
+        }
+        while (!*next) {
+            /* parent is already processed, go to its sibling */
+            *elem = (struct lyd_node *)(*elem)->parent;
+            /* no siblings, go back through parents */
+            if ((*elem)->parent == (*start)->parent) {
+                /* we are done, no next element to process */
+                break;
+            }
+            *next = (*elem)->next;
+        }
     }
 
     if (!*next) {