xml parser REFACTOR parse subtrees instead of siblings
diff --git a/src/parser_xml.c b/src/parser_xml.c
index ffca41f..58508f6 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -377,7 +377,7 @@
 }
 
 /**
- * @brief Parse XML elements as YANG data node children the specified parent node.
+ * @brief Parse XML subtree.
  *
  * @param[in] lydctx XML YANG data parser context.
  * @param[in] parent Parent node where the children are inserted. NULL in case of parsing top-level elements.
@@ -385,7 +385,7 @@
  * @return LY_ERR value.
  */
 static LY_ERR
-lydxml_data_r(struct lyd_xml_ctx *lydctx, struct lyd_node_inner *parent, struct lyd_node **first)
+lydxml_subtree_r(struct lyd_xml_ctx *lydctx, struct lyd_node_inner *parent, struct lyd_node **first_p)
 {
     LY_ERR ret = LY_SUCCESS;
     const char *prefix, *name;
@@ -393,12 +393,12 @@
     struct lyxml_ctx *xmlctx;
     const struct ly_ctx *ctx;
     const struct lyxml_ns *ns;
-    struct lyd_meta *meta = NULL, *m;
-    struct lyd_attr *attr = NULL, *a;
+    struct lyd_meta *meta = NULL;
+    struct lyd_attr *attr = NULL;
     const struct lysc_node *snode;
     struct lys_module *mod;
     uint32_t prev_opts;
-    struct lyd_node *cur = NULL, *anchor;
+    struct lyd_node *node = NULL, *anchor;
     struct ly_prefix *val_prefs;
     int getnext_opts;
 
@@ -407,248 +407,236 @@
     /* leave if-feature check for validation */
     getnext_opts = LYS_GETNEXT_NOSTATECHECK | (lydctx->int_opts & LYD_INTOPT_REPLY ? LYS_GETNEXT_OUTPUT : 0);
 
-    while (xmlctx->status == LYXML_ELEMENT) {
-        /* remember element prefix and name */
-        prefix = xmlctx->prefix;
-        prefix_len = xmlctx->prefix_len;
-        name = xmlctx->name;
-        name_len = xmlctx->name_len;
+    assert(xmlctx->status == LYXML_ELEMENT);
 
-        /* get the element module */
-        ns = lyxml_ns_get(xmlctx, prefix, prefix_len);
-        if (!ns) {
-            LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".",
-                   prefix_len, prefix);
+    /* remember element prefix and name */
+    prefix = xmlctx->prefix;
+    prefix_len = xmlctx->prefix_len;
+    name = xmlctx->name;
+    name_len = xmlctx->name_len;
+
+    /* get the element module */
+    ns = lyxml_ns_get(xmlctx, prefix, prefix_len);
+    if (!ns) {
+        LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".",
+               prefix_len, prefix);
+        ret = LY_EVALID;
+        goto error;
+    }
+    mod = ly_ctx_get_module_implemented_ns(ctx, ns->uri);
+    if (!mod) {
+        if (lydctx->parse_options & LYD_PARSE_STRICT) {
+            LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "No module with namespace \"%s\" in the context.",
+                   ns->uri);
             ret = LY_EVALID;
-            goto cleanup;
+            goto error;
         }
-        mod = ly_ctx_get_module_implemented_ns(ctx, ns->uri);
-        if (!mod) {
-            if (lydctx->parse_options & LYD_PARSE_STRICT) {
-                LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "No module with namespace \"%s\" in the context.",
-                       ns->uri);
-                ret = LY_EVALID;
-                goto cleanup;
-            }
-            if (!(lydctx->parse_options & LYD_PARSE_OPAQ)) {
-                /* skip element with children */
-                LY_CHECK_GOTO(ret = lydxml_data_skip(xmlctx), cleanup);
-                continue;
-            }
+        if (!(lydctx->parse_options & LYD_PARSE_OPAQ)) {
+            /* skip element with children */
+            LY_CHECK_GOTO(ret = lydxml_data_skip(xmlctx), error);
+            return LY_SUCCESS;
         }
-
-        /* parser next */
-        LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
-
-        /* get the schema node */
-        snode = NULL;
-        if (mod && (!parent || parent->schema)) {
-            snode = lys_find_child(parent ? parent->schema : NULL, mod, name, name_len, 0, getnext_opts);
-            if (!snode) {
-                if (lydctx->parse_options & LYD_PARSE_STRICT) {
-                    LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "Element \"%.*s\" not found in the \"%s\" module.",
-                        name_len, name, mod->name);
-                    ret = LY_EVALID;
-                    goto cleanup;
-                } else if (!(lydctx->parse_options & LYD_PARSE_OPAQ)) {
-                    /* skip element with children */
-                    LY_CHECK_GOTO(ret = lydxml_data_skip(xmlctx), cleanup);
-                    continue;
-                }
-            } else {
-                /* check that schema node is valid and can be used */
-                LY_CHECK_GOTO(ret = lyd_parser_check_schema((struct lyd_ctx *)lydctx, snode), cleanup);
-                LY_CHECK_GOTO(ret = lydxml_data_check_opaq(lydctx, &snode), cleanup);
-            }
-        }
-
-        /* create metadata/attributes */
-        if (xmlctx->status == LYXML_ATTRIBUTE) {
-            if (snode) {
-                ret = lydxml_metadata(lydctx, snode, &meta);
-                LY_CHECK_GOTO(ret, cleanup);
-            } else {
-                assert(lydctx->parse_options & LYD_PARSE_OPAQ);
-                ret = lydxml_attrs(xmlctx, &attr);
-                LY_CHECK_GOTO(ret, cleanup);
-            }
-        }
-
-        assert(xmlctx->status == LYXML_ELEM_CONTENT);
-        if (!snode) {
-            assert(lydctx->parse_options & LYD_PARSE_OPAQ);
-
-            if (xmlctx->ws_only) {
-                /* ignore WS-only value */
-                xmlctx->value_len = 0;
-                val_prefs = NULL;
-            } else {
-                /* get value prefixes */
-                ret = lyxml_get_prefixes(xmlctx, xmlctx->value, xmlctx->value_len, &val_prefs);
-                LY_CHECK_GOTO(ret, cleanup);
-            }
-
-            /* create node */
-            ret = lyd_create_opaq(ctx, name, name_len, xmlctx->value, xmlctx->value_len, &xmlctx->dynamic, 0, LYD_XML,
-                                  val_prefs, prefix, prefix_len, ns->uri, strlen(ns->uri), &cur);
-            LY_CHECK_GOTO(ret, cleanup);
-
-            /* parser next */
-            LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
-
-            /* process children */
-            if (xmlctx->status == LYXML_ELEMENT) {
-                ret = lydxml_data_r(lydctx, (struct lyd_node_inner *)cur, lyd_node_children_p(cur));
-                LY_CHECK_GOTO(ret, cleanup);
-            }
-        } else if (snode->nodetype & LYD_NODE_TERM) {
-            /* create node */
-            LY_CHECK_GOTO(ret = lyd_parser_create_term((struct lyd_ctx*)lydctx, snode, xmlctx->value, xmlctx->value_len, &xmlctx->dynamic, 0,
-                                                       lydxml_resolve_prefix, xmlctx, LYD_XML, &cur), cleanup);
-
-            if (parent && (cur->schema->flags & LYS_KEY)) {
-                /* check the key order, the anchor must never be a key */
-                anchor = lyd_insert_get_next_anchor(parent->child, cur);
-                if (anchor && (anchor->schema->flags & LYS_KEY)) {
-                    if (lydctx->parse_options & LYD_PARSE_STRICT) {
-                        LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_DATA, "Invalid position of the key \"%s\" in a list.",
-                                cur->schema->name);
-                        ret = LY_EVALID;
-                        goto cleanup;
-                    } else {
-                        LOGWRN(ctx, "Invalid position of the key \"%s\" in a list.", cur->schema->name);
-                    }
-                }
-            }
-
-            /* parser next */
-            LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
-
-            /* no children expected */
-            if (xmlctx->status == LYXML_ELEMENT) {
-                LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Child element \"%.*s\" inside a terminal node \"%s\" found.",
-                       xmlctx->name_len, xmlctx->name, snode->name);
-                ret = LY_EVALID;
-                goto cleanup;
-            }
-        } else if (snode->nodetype & LYD_NODE_INNER) {
-            if (!xmlctx->ws_only) {
-                /* value in inner node */
-                LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Text value \"%.*s\" inside an inner node \"%s\" found.",
-                       xmlctx->value_len, xmlctx->value, snode->name);
-                ret = LY_EVALID;
-                goto cleanup;
-            }
-
-            /* create node */
-            ret = lyd_create_inner(snode, &cur);
-            LY_CHECK_GOTO(ret, cleanup);
-
-            /* parser next */
-            LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
-
-            /* process children */
-            if (xmlctx->status == LYXML_ELEMENT) {
-                ret = lydxml_data_r(lydctx, (struct lyd_node_inner *)cur, lyd_node_children_p(cur));
-                LY_CHECK_GOTO(ret, cleanup);
-            }
-
-            if (snode->nodetype == LYS_LIST) {
-                /* check all keys exist */
-                LY_CHECK_GOTO(ret = lyd_parse_check_keys(cur), cleanup);
-            }
-
-            if (!(lydctx->parse_options & LYD_PARSE_ONLY)) {
-                /* new node validation, autodelete CANNOT occur, all nodes are new */
-                ret = lyd_validate_new(lyd_node_children_p(cur), snode, NULL, NULL);
-                LY_CHECK_GOTO(ret, cleanup);
-
-                /* add any missing default children */
-                ret = lyd_new_implicit_r(cur, lyd_node_children_p(cur), NULL, NULL, &lydctx->unres_node_type, &lydctx->when_check,
-                                         (lydctx->validate_options & LYD_VALIDATE_NO_STATE) ? LYD_IMPLICIT_NO_STATE : 0, NULL);
-                LY_CHECK_GOTO(ret, cleanup);
-            }
-
-            if (snode->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF)) {
-                /* rememeber the RPC/action/notification */
-                lydctx->op_node = cur;
-            }
-        } else if (snode->nodetype & LYD_NODE_ANY) {
-            if (!xmlctx->ws_only) {
-                /* value in inner node */
-                LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Text value \"%.*s\" inside an any node \"%s\" found.",
-                       xmlctx->value_len, xmlctx->value, snode->name);
-                ret = LY_EVALID;
-                goto cleanup;
-            }
-
-            /* parser next */
-            LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
-
-            /* parse any data tree with correct options */
-            prev_opts = lydctx->parse_options;
-            lydctx->parse_options &= ~LYD_PARSE_STRICT;
-            lydctx->parse_options |= LYD_PARSE_OPAQ;
-            anchor = NULL;
-            ret = lydxml_data_r(lydctx, NULL, &anchor);
-            lydctx->parse_options = prev_opts;
-            LY_CHECK_GOTO(ret, cleanup);
-
-            /* create node */
-            ret = lyd_create_any(snode, anchor, LYD_ANYDATA_DATATREE, &cur);
-            LY_CHECK_GOTO(ret, cleanup);
-        }
-        assert(cur);
-
-        /* add/correct flags */
-        if (snode) {
-            lyd_parse_set_data_flags(cur, &lydctx->when_check, &meta, lydctx->parse_options);
-        }
-
-        /* add metadata/attributes */
-        if (snode) {
-            LY_LIST_FOR(meta, m) {
-                m->parent = cur;
-            }
-            cur->meta = meta;
-            meta = NULL;
-        } else {
-            assert(!cur->schema);
-            LY_LIST_FOR(attr, a) {
-                a->parent = (struct lyd_node_opaq *)cur;
-            }
-            ((struct lyd_node_opaq *)cur)->attr = attr;
-            attr = NULL;
-        }
-
-        /* insert, keep first pointer correct */
-        lyd_insert_node((struct lyd_node *)parent, first, cur);
-        while (!parent && (*first)->prev->next) {
-            *first = (*first)->prev;
-        }
-        cur = NULL;
-
-        /* parser next */
-        assert(xmlctx->status == LYXML_ELEM_CLOSE);
-        LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
     }
 
-    /* success */
-    ret = LY_SUCCESS;
+    /* parser next */
+    LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), error);
 
-cleanup:
+    /* get the schema node */
+    snode = NULL;
+    if (mod && (!parent || parent->schema)) {
+        snode = lys_find_child(parent ? parent->schema : NULL, mod, name, name_len, 0, getnext_opts);
+        if (!snode) {
+            if (lydctx->parse_options & LYD_PARSE_STRICT) {
+                LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "Element \"%.*s\" not found in the \"%s\" module.",
+                       name_len, name, mod->name);
+                ret = LY_EVALID;
+                goto error;
+            } else if (!(lydctx->parse_options & LYD_PARSE_OPAQ)) {
+                /* skip element with children */
+                LY_CHECK_GOTO(ret = lydxml_data_skip(xmlctx), error);
+                return LY_SUCCESS;
+            }
+        } else {
+            /* check that schema node is valid and can be used */
+            LY_CHECK_GOTO(ret = lyd_parser_check_schema((struct lyd_ctx *)lydctx, snode), error);
+            LY_CHECK_GOTO(ret = lydxml_data_check_opaq(lydctx, &snode), error);
+        }
+    }
+
+    /* create metadata/attributes */
+    if (xmlctx->status == LYXML_ATTRIBUTE) {
+        if (snode) {
+            ret = lydxml_metadata(lydctx, snode, &meta);
+            LY_CHECK_GOTO(ret, error);
+        } else {
+            assert(lydctx->parse_options & LYD_PARSE_OPAQ);
+            ret = lydxml_attrs(xmlctx, &attr);
+            LY_CHECK_GOTO(ret, error);
+        }
+    }
+
+    assert(xmlctx->status == LYXML_ELEM_CONTENT);
+    if (!snode) {
+        assert(lydctx->parse_options & LYD_PARSE_OPAQ);
+
+        if (xmlctx->ws_only) {
+            /* ignore WS-only value */
+            xmlctx->value_len = 0;
+            val_prefs = NULL;
+        } else {
+            /* get value prefixes */
+            ret = lyxml_get_prefixes(xmlctx, xmlctx->value, xmlctx->value_len, &val_prefs);
+            LY_CHECK_GOTO(ret, error);
+        }
+
+        /* create node */
+        ret = lyd_create_opaq(ctx, name, name_len, xmlctx->value, xmlctx->value_len, &xmlctx->dynamic, 0, LYD_XML,
+                              val_prefs, prefix, prefix_len, ns->uri, strlen(ns->uri), &node);
+        LY_CHECK_GOTO(ret, error);
+
+        /* parser next */
+        LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), error);
+
+        /* process children */
+        while (xmlctx->status == LYXML_ELEMENT) {
+            ret = lydxml_subtree_r(lydctx, (struct lyd_node_inner *)node, lyd_node_children_p(node));
+            LY_CHECK_GOTO(ret, error);
+        }
+    } else if (snode->nodetype & LYD_NODE_TERM) {
+        /* create node */
+        LY_CHECK_GOTO(ret = lyd_parser_create_term((struct lyd_ctx*)lydctx, snode, xmlctx->value, xmlctx->value_len,
+                                        &xmlctx->dynamic, 0, lydxml_resolve_prefix, xmlctx, LYD_XML, &node), error);
+
+        if (parent && (node->schema->flags & LYS_KEY)) {
+            /* check the key order, the anchor must never be a key */
+            anchor = lyd_insert_get_next_anchor(parent->child, node);
+            if (anchor && (anchor->schema->flags & LYS_KEY)) {
+                if (lydctx->parse_options & LYD_PARSE_STRICT) {
+                    LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_DATA, "Invalid position of the key \"%s\" in a list.",
+                           node->schema->name);
+                    ret = LY_EVALID;
+                    goto error;
+                } else {
+                    LOGWRN(ctx, "Invalid position of the key \"%s\" in a list.", node->schema->name);
+                }
+            }
+        }
+
+        /* parser next */
+        LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), error);
+
+        /* no children expected */
+        if (xmlctx->status == LYXML_ELEMENT) {
+            LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Child element \"%.*s\" inside a terminal node \"%s\" found.",
+                   xmlctx->name_len, xmlctx->name, snode->name);
+            ret = LY_EVALID;
+            goto error;
+        }
+    } else if (snode->nodetype & LYD_NODE_INNER) {
+        if (!xmlctx->ws_only) {
+            /* value in inner node */
+            LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Text value \"%.*s\" inside an inner node \"%s\" found.",
+                   xmlctx->value_len, xmlctx->value, snode->name);
+            ret = LY_EVALID;
+            goto error;
+        }
+
+        /* create node */
+        ret = lyd_create_inner(snode, &node);
+        LY_CHECK_GOTO(ret, error);
+
+        /* parser next */
+        LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), error);
+
+        /* process children */
+        while (xmlctx->status == LYXML_ELEMENT) {
+            ret = lydxml_subtree_r(lydctx, (struct lyd_node_inner *)node, lyd_node_children_p(node));
+            LY_CHECK_GOTO(ret, error);
+        }
+
+        if (snode->nodetype == LYS_LIST) {
+            /* check all keys exist */
+            LY_CHECK_GOTO(ret = lyd_parse_check_keys(node), error);
+        }
+
+        if (!(lydctx->parse_options & LYD_PARSE_ONLY)) {
+            /* new node validation, autodelete CANNOT occur, all nodes are new */
+            ret = lyd_validate_new(lyd_node_children_p(node), snode, NULL, NULL);
+            LY_CHECK_GOTO(ret, error);
+
+            /* add any missing default children */
+            ret = lyd_new_implicit_r(node, lyd_node_children_p(node), NULL, NULL, &lydctx->unres_node_type, &lydctx->when_check,
+                                     (lydctx->validate_options & LYD_VALIDATE_NO_STATE) ? LYD_IMPLICIT_NO_STATE : 0, NULL);
+            LY_CHECK_GOTO(ret, error);
+        }
+
+        if (snode->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF)) {
+            /* rememeber the RPC/action/notification */
+            lydctx->op_node = node;
+        }
+    } else if (snode->nodetype & LYD_NODE_ANY) {
+        if (!xmlctx->ws_only) {
+            /* value in inner node */
+            LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Text value \"%.*s\" inside an any node \"%s\" found.",
+                   xmlctx->value_len, xmlctx->value, snode->name);
+            ret = LY_EVALID;
+            goto error;
+        }
+
+        /* parser next */
+        LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), error);
+
+        /* parse any data tree with correct options */
+        prev_opts = lydctx->parse_options;
+        lydctx->parse_options &= ~LYD_PARSE_STRICT;
+        lydctx->parse_options |= LYD_PARSE_OPAQ;
+        anchor = NULL;
+        while (xmlctx->status == LYXML_ELEMENT) {
+            ret = lydxml_subtree_r(lydctx, NULL, &anchor);
+            LY_CHECK_ERR_GOTO(ret, lydctx->parse_options = prev_opts, error);
+        }
+        lydctx->parse_options = prev_opts;
+
+        /* create node */
+        ret = lyd_create_any(snode, anchor, LYD_ANYDATA_DATATREE, &node);
+        LY_CHECK_GOTO(ret, error);
+    }
+    assert(node);
+
+    /* add/correct flags */
+    if (snode) {
+        lyd_parse_set_data_flags(node, &lydctx->when_check, &meta, lydctx->parse_options);
+    }
+
+    /* parser next */
+    assert(xmlctx->status == LYXML_ELEM_CLOSE);
+    LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), error);
+
+    /* add metadata/attributes */
+    if (snode) {
+        lyd_insert_meta(node, meta);
+    } else {
+        lyd_insert_attr(node, attr);
+    }
+
+    /* insert, keep first pointer correct */
+    lyd_insert_node((struct lyd_node *)parent, first_p, node);
+    while (!parent && (*first_p)->prev->next) {
+        *first_p = (*first_p)->prev;
+    }
+
+    return LY_SUCCESS;
+
+error:
     lyd_free_meta_siblings(meta);
     ly_free_attr_siblings(ctx, attr);
-    lyd_free_tree(cur);
-    if (ret && *first) {
-        lyd_free_siblings(*first);
-        *first = NULL;
-    }
+    lyd_free_tree(node);
     return ret;
 }
 
 LY_ERR
-lyd_parse_xml_data(const struct ly_ctx *ctx, struct ly_in *in, int parse_options, int validate_options, struct lyd_node **tree_p, struct lyd_ctx **lydctx_p)
+lyd_parse_xml_data(const struct ly_ctx *ctx, struct ly_in *in, int parse_options, int validate_options,
+                   struct lyd_node **tree_p, struct lyd_ctx **lydctx_p)
 {
     LY_ERR ret = LY_SUCCESS;
     struct lyd_xml_ctx *lydctx;
@@ -666,7 +654,9 @@
     lydctx->resolve_prefix = lydxml_resolve_prefix;
 
     /* parse XML data */
-    LY_CHECK_GOTO(ret = lydxml_data_r(lydctx, NULL, tree_p), cleanup);
+    while (lydctx->xmlctx->status == LYXML_ELEMENT) {
+        LY_CHECK_GOTO(ret = lydxml_subtree_r(lydctx, NULL, tree_p), cleanup);
+    }
 
 cleanup:
     /* there should be no unresolved types stored */
@@ -765,7 +755,9 @@
     }
 
     /* parse the rest of data normally */
-    LY_CHECK_GOTO(ret = lydxml_data_r(&lydctx, NULL, &tree), cleanup);
+    while (lydctx.xmlctx->status == LYXML_ELEMENT) {
+        LY_CHECK_GOTO(ret = lydxml_subtree_r(&lydctx, NULL, &tree), cleanup);
+    }
 
     /* make sure we have parsed some operation */
     if (!lydctx.op_node) {
@@ -947,7 +939,9 @@
     LY_CHECK_GOTO(ret = lydxml_notif_envelope(lydctx.xmlctx, &ntf_e), cleanup);
 
     /* parse the rest of data normally */
-    LY_CHECK_GOTO(ret = lydxml_data_r(&lydctx, NULL, &tree), cleanup);
+    while (lydctx.xmlctx->status == LYXML_ELEMENT) {
+        LY_CHECK_GOTO(ret = lydxml_subtree_r(&lydctx, NULL, &tree), cleanup);
+    }
 
     /* make sure we have parsed some notification */
     if (!lydctx.op_node) {
@@ -1027,7 +1021,10 @@
                   cleanup);
 
     /* parse the rest of data normally but connect them to the duplicated operation */
-    LY_CHECK_GOTO(ret = lydxml_data_r(&lydctx, (struct lyd_node_inner *)rep_op, lyd_node_children_p(rep_op)), cleanup);
+    while (lydctx.xmlctx->status == LYXML_ELEMENT) {
+        ret = lydxml_subtree_r(&lydctx, (struct lyd_node_inner *)rep_op, lyd_node_children_p(rep_op));
+        LY_CHECK_GOTO(ret, cleanup);
+    }
 
     /* finish XML parsing and check operation type */
     if (rpcr_e) {