data tree REFACTOR opaq name and its module information structure

Put the node name and its module into a separate
structure to follow lyd_node's schema and the
information it stores.
diff --git a/src/parser_json.c b/src/parser_json.c
index 96cb93d..ad531e0 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -159,11 +159,11 @@
             break;
         }
         onode = (struct lyd_node_opaq *)node;
-        if (onode->prefix.module_name) {
-            *prefix_p = onode->prefix.module_name;
+        if (onode->name.module_name) {
+            *prefix_p = onode->name.module_name;
             break;
-        } else if (onode->prefix.id) {
-            *prefix_p = onode->prefix.id;
+        } else if (onode->name.prefix) {
+            *prefix_p = onode->name.prefix;
             break;
         }
         node = (struct lyd_node *)node->parent;
@@ -503,15 +503,15 @@
         size_t name_len, prefix_len;
         const struct lysc_node *snode;
 
-        if (attr->schema || (meta_container->name[0] != '@')) {
+        if (attr->schema || (meta_container->name.name[0] != '@')) {
             /* not an opaq metadata node */
             continue;
         }
 
-        if (prev != meta_container->name) {
+        if (prev != meta_container->name.name) {
             /* metas' names are stored in dictionary, so checking pointers must works */
             lydict_remove(lydctx->jsonctx->ctx, prev);
-            LY_CHECK_GOTO(ret = lydict_insert(lydctx->jsonctx->ctx, meta_container->name, 0, &prev), cleanup);
+            LY_CHECK_GOTO(ret = lydict_insert(lydctx->jsonctx->ctx, meta_container->name.name, 0, &prev), cleanup);
             instance = 1;
         } else {
             instance++;
@@ -521,13 +521,13 @@
         LY_LIST_FOR(start, node) {
             if (!node->schema) {
                 /* opaq node - we are going to put into it just a generic attribute. */
-                if (strcmp(&meta_container->name[1], ((struct lyd_node_opaq *)node)->name)) {
+                if (strcmp(&meta_container->name.name[1], ((struct lyd_node_opaq *)node)->name.name)) {
                     continue;
                 }
 
                 if (((struct lyd_node_opaq *)node)->hints & LYD_NODEHINT_LIST) {
                     LOGVAL(lydctx->jsonctx->ctx, LY_VLOG_LYD, node, LYVE_SYNTAX,
-                            "Metadata container references a sibling list node %s.", ((struct lyd_node_opaq *)node)->name);
+                            "Metadata container references a sibling list node %s.", ((struct lyd_node_opaq *)node)->name.name);
                     ret = LY_EVALID;
                     goto cleanup;
                 }
@@ -541,9 +541,10 @@
                 LY_LIST_FOR(meta_container->child, meta_iter) {
                     /* convert opaq node to a attribute of the opaq node */
                     struct lyd_node_opaq *meta = (struct lyd_node_opaq *)meta_iter;
-                    ret = lyd_create_attr(node, NULL, lydctx->jsonctx->ctx, meta->name, strlen(meta->name), meta->prefix.id,
-                            ly_strlen(meta->prefix.id), meta->prefix.module_name, ly_strlen(meta->prefix.module_name),
-                            meta->value, ly_strlen(meta->value), NULL, LY_PREF_JSON, NULL, meta->hints);
+                    ret = lyd_create_attr(node, NULL, lydctx->jsonctx->ctx, meta->name.name, strlen(meta->name.name),
+                            meta->name.prefix, ly_strlen(meta->name.prefix), meta->name.module_name,
+                            ly_strlen(meta->name.module_name), meta->value, ly_strlen(meta->value), NULL, LY_PREF_JSON,
+                            NULL, meta->hints);
                     LY_CHECK_GOTO(ret, cleanup);
                 }
 
@@ -552,7 +553,8 @@
             } else {
                 /* this is the second time we are resolving the schema node, so it must succeed,
                  * but remember that snode can be still NULL */
-                lydjson_parse_name(meta_container->name, strlen(meta_container->name), &name, &name_len, &prefix, &prefix_len, &is_attr);
+                lydjson_parse_name(meta_container->name.name, strlen(meta_container->name.name), &name, &name_len,
+                        &prefix, &prefix_len, &is_attr);
                 assert(is_attr);
                 ret = lydjson_get_snode(lydctx, is_attr, prefix, prefix_len, name, name_len, (*first_p)->parent, &snode);
                 assert(ret == LY_SUCCESS);
@@ -573,16 +575,16 @@
                     struct lys_module *mod = NULL;
                     ly_bool dynamic = 0;
 
-                    mod = ly_ctx_get_module_implemented(lydctx->jsonctx->ctx, meta->prefix.id);
+                    mod = ly_ctx_get_module_implemented(lydctx->jsonctx->ctx, meta->name.prefix);
                     if (mod) {
                         ret = lyd_parser_create_meta((struct lyd_ctx *)lydctx, node, NULL, mod,
-                                meta->name, strlen(meta->name), meta->value, ly_strlen(meta->value),
+                                meta->name.name, strlen(meta->name.name), meta->value, ly_strlen(meta->value),
                                 &dynamic, LY_PREF_JSON, NULL, meta->hints);
                         LY_CHECK_GOTO(ret, cleanup);
                     } else if (lydctx->parse_options & LYD_PARSE_STRICT) {
                         LOGVAL(lydctx->jsonctx->ctx, LY_VLOG_LYD, node, LYVE_REFERENCE,
                                 "Unknown (or not implemented) YANG module \"%s\" for metadata \"%s%s%s\".",
-                                meta->prefix.id, meta->prefix.id, ly_strlen(meta->prefix.id) ? ":" : "", meta->name);
+                                meta->name.prefix, meta->name.prefix, ly_strlen(meta->name.prefix) ? ":" : "", meta->name.name);
                         ret = LY_EVALID;
                         goto cleanup;
                     }
@@ -600,10 +602,10 @@
             if (instance > 1) {
                 LOGVAL(lydctx->jsonctx->ctx, LY_VLOG_LYD, *first_p ? (*first_p)->parent : NULL, LYVE_REFERENCE,
                         "Missing %d%s JSON data instance to be coupled with %s metadata.", instance,
-                        instance == 2 ? "nd" : (instance == 3 ? "rd" : "th"), meta_container->name);
+                        instance == 2 ? "nd" : (instance == 3 ? "rd" : "th"), meta_container->name.name);
             } else {
                 LOGVAL(lydctx->jsonctx->ctx, LY_VLOG_LYD, *first_p ? (*first_p)->parent : NULL, LYVE_REFERENCE,
-                        "Missing JSON data instance to be coupled with %s metadata.", meta_container->name);
+                        "Missing JSON data instance to be coupled with %s metadata.", meta_container->name.name);
             }
             ret = LY_EVALID;
         } else {
@@ -802,7 +804,7 @@
 representation_error:
     LOGVAL(ctx, LY_VLOG_LYD, (void *)node, LYVE_SYNTAX_JSON,
             "The attribute(s) of %s \"%s\" is expected to be represented as JSON %s, but input data contains @%s/%s.",
-            lys_nodetype2str(nodetype), node->schema ? node->schema->name : ((struct lyd_node_opaq *)node)->name,
+            lys_nodetype2str(nodetype), node->schema ? node->schema->name : ((struct lyd_node_opaq *)node)->name.name,
             expected, lyjson_token2str(status), in_parent ? "" : "name");
 
     return LY_EVALID;
diff --git a/src/printer_json.c b/src/printer_json.c
index 2bc64ad..0c10df9 100644
--- a/src/printer_json.c
+++ b/src/printer_json.c
@@ -79,7 +79,7 @@
         /* compare node names */
         struct lyd_node_opaq *onode1 = (struct lyd_node_opaq *)node1;
         struct lyd_node_opaq *onode2 = (struct lyd_node_opaq *)node2;
-        if ((onode1->name != onode2->name) || (onode1->prefix.id != onode2->prefix.id)) {
+        if ((onode1->name.name != onode2->name.name) || (onode1->name.prefix != onode2->name.prefix)) {
             return 0;
         }
     }
@@ -160,9 +160,9 @@
 
         switch (onode->format) {
         case LY_PREF_JSON:
-            return onode->prefix.module_name;
+            return onode->name.module_name;
         case LY_PREF_XML:
-            mod = ly_ctx_get_module_implemented_ns(onode->ctx, onode->prefix.module_ns);
+            mod = ly_ctx_get_module_implemented_ns(onode->ctx, onode->name.module_ns);
             if (!mod) {
                 return NULL;
             }
@@ -283,29 +283,28 @@
  * @param[in] ctx JSON printer context.
  * @param[in] parent Parent node to compare modules deciding if the prefix is printed.
  * @param[in] format Format to decide how to process the @p prefix.
- * @param[in] prefix Prefix structure to provide prefix string if prefix to print.
- * @param[in] name Name of the memeber to print.
+ * @param[in] name Name structure to provide name and prefix to print. If NULL, only "" name is printed.
  * @param[in] is_attr Flag if the metadata sign (@) is supposed to be added before the identifier.
  * @return LY_ERR value.
  */
 static LY_ERR
 json_print_member2(struct jsonpr_ctx *ctx, const struct lyd_node *parent, LY_PREFIX_FORMAT format,
-        const struct ly_prefix *prefix, const char *name, ly_bool is_attr)
+        const struct ly_opaq_name *name, ly_bool is_attr)
 {
-    const char *module_name = NULL;
+    const char *module_name = NULL, *name_str;
 
     PRINT_COMMA;
 
     /* determine prefix string */
-    if (prefix) {
+    if (name) {
         const struct lys_module *mod;
 
         switch (format) {
         case LY_PREF_JSON:
-            module_name = prefix->module_name;
+            module_name = name->module_name;
             break;
         case LY_PREF_XML:
-            mod = ly_ctx_get_module_implemented_ns(ctx->ctx, prefix->module_ns);
+            mod = ly_ctx_get_module_implemented_ns(ctx->ctx, name->module_ns);
             if (mod) {
                 module_name = mod->name;
             }
@@ -314,13 +313,17 @@
             /* cannot be created */
             LOGINT_RET(ctx->ctx);
         }
+
+        name_str = name->name;
+    } else {
+        name_str = "";
     }
 
     /* print the member */
     if (module_name && (!parent || (node_prefix(parent) != module_name))) {
-        ly_print_(ctx->out, "%*s\"%s%s:%s\":%s", INDENT, is_attr ? "@" : "", module_name, name, DO_FORMAT ? " " : "");
+        ly_print_(ctx->out, "%*s\"%s%s:%s\":%s", INDENT, is_attr ? "@" : "", module_name, name_str, DO_FORMAT ? " " : "");
     } else {
-        ly_print_(ctx->out, "%*s\"%s%s\":%s", INDENT, is_attr ? "@" : "", name, DO_FORMAT ? " " : "");
+        ly_print_(ctx->out, "%*s\"%s%s\":%s", INDENT, is_attr ? "@" : "", name_str, DO_FORMAT ? " " : "");
     }
 
     return LY_SUCCESS;
@@ -400,7 +403,7 @@
 
     for (attr = node->attr; attr; attr = attr->next) {
         PRINT_COMMA;
-        json_print_member2(ctx, (struct lyd_node *)node, attr->format, &attr->prefix, attr->name, 0);
+        json_print_member2(ctx, (struct lyd_node *)node, attr->format, &attr->name, 0);
 
         if (attr->hints & (LYD_VALHINT_BOOLEAN | LYD_VALHINT_DECNUM)) {
             ly_print_(ctx->out, "%s", attr->value[0] ? attr->value : "null");
@@ -464,7 +467,7 @@
 
     if (node->schema && node->meta) {
         if (inner) {
-            LY_CHECK_RET(json_print_member2(ctx, NULL, LY_PREF_JSON, NULL, "", 1));
+            LY_CHECK_RET(json_print_member2(ctx, NULL, LY_PREF_JSON, NULL, 1));
         } else {
             LY_CHECK_RET(json_print_member(ctx, node, 1));
         }
@@ -476,10 +479,10 @@
         LEVEL_PRINTED;
     } else if (!node->schema && ((struct lyd_node_opaq *)node)->attr) {
         if (inner) {
-            LY_CHECK_RET(json_print_member2(ctx, NULL, LY_PREF_JSON, NULL, "", 1));
+            LY_CHECK_RET(json_print_member2(ctx, NULL, LY_PREF_JSON, NULL, 1));
         } else {
             LY_CHECK_RET(json_print_member2(ctx, node, ((struct lyd_node_opaq *)node)->format,
-                    &((struct lyd_node_opaq *)node)->prefix, ((struct lyd_node_opaq *)node)->name, 1));
+                    &((struct lyd_node_opaq *)node)->name, 1));
         }
         ly_print_(ctx->out, "{%s", (DO_FORMAT ? "\n" : ""));
         LEVEL_INC;
@@ -767,7 +770,7 @@
     }
 
     if (first) {
-        LY_CHECK_RET(json_print_member2(ctx, node->parent, node->format, &node->prefix, node->name, 0));
+        LY_CHECK_RET(json_print_member2(ctx, node->parent, node->format, &node->name, 0));
 
         if (node->hints & (LYD_NODEHINT_LIST | LYD_NODEHINT_LEAFLIST)) {
             LY_CHECK_RET(json_print_array_open(ctx, (struct lyd_node *)node));
diff --git a/src/printer_lyb.c b/src/printer_lyb.c
index bb5cc9e..1282ff0 100644
--- a/src/printer_lyb.c
+++ b/src/printer_lyb.c
@@ -611,13 +611,13 @@
 lyb_print_opaq(struct lyd_node_opaq *opaq, struct ly_out *out, struct lylyb_ctx *lybctx)
 {
     /* prefix */
-    LY_CHECK_RET(lyb_write_string(opaq->prefix.id, 0, 1, out, lybctx));
+    LY_CHECK_RET(lyb_write_string(opaq->name.prefix, 0, 1, out, lybctx));
 
     /* module reference */
-    LY_CHECK_RET(lyb_write_string(opaq->prefix.module_name, 0, 1, out, lybctx));
+    LY_CHECK_RET(lyb_write_string(opaq->name.module_name, 0, 1, out, lybctx));
 
     /* name */
-    LY_CHECK_RET(lyb_write_string(opaq->name, 0, 1, out, lybctx));
+    LY_CHECK_RET(lyb_write_string(opaq->name.name, 0, 1, out, lybctx));
 
     /* format */
     LY_CHECK_RET(lyb_write_number(opaq->format, 1, out, lybctx));
@@ -799,13 +799,13 @@
         LY_CHECK_RET(lyb_write_start_subtree(out, lybctx));
 
         /* prefix */
-        LY_CHECK_RET(lyb_write_string(iter->prefix.id, 0, 1, out, lybctx));
+        LY_CHECK_RET(lyb_write_string(iter->name.prefix, 0, 1, out, lybctx));
 
         /* namespace */
-        LY_CHECK_RET(lyb_write_string(iter->prefix.module_name, 0, 1, out, lybctx));
+        LY_CHECK_RET(lyb_write_string(iter->name.module_name, 0, 1, out, lybctx));
 
         /* name */
-        LY_CHECK_RET(lyb_write_string(iter->name, 0, 1, out, lybctx));
+        LY_CHECK_RET(lyb_write_string(iter->name.name, 0, 1, out, lybctx));
 
         /* format */
         LY_CHECK_RET(lyb_write_number(iter->format, 1, out, lybctx));
diff --git a/src/printer_xml.c b/src/printer_xml.c
index 7108863..56a1b43 100644
--- a/src/printer_xml.c
+++ b/src/printer_xml.c
@@ -105,17 +105,17 @@
 }
 
 static const char *
-xml_print_ns_opaq(struct xmlpr_ctx *ctx, LY_PREFIX_FORMAT format, const struct ly_prefix *prefix, uint32_t prefix_opts)
+xml_print_ns_opaq(struct xmlpr_ctx *ctx, LY_PREFIX_FORMAT format, const struct ly_opaq_name *name, uint32_t prefix_opts)
 {
     switch (format) {
     case LY_PREF_XML:
-        return xml_print_ns(ctx, prefix->module_ns, (prefix_opts & LYXML_PREFIX_DEFAULT) ? NULL : prefix->id, prefix_opts);
+        return xml_print_ns(ctx, name->module_ns, (prefix_opts & LYXML_PREFIX_DEFAULT) ? NULL : name->prefix, prefix_opts);
         break;
     case LY_PREF_JSON:
-        if (prefix->module_name) {
-            const struct lys_module *mod = ly_ctx_get_module_latest(ctx->ctx, prefix->module_name);
+        if (name->module_name) {
+            const struct lys_module *mod = ly_ctx_get_module_latest(ctx->ctx, name->module_name);
             if (mod) {
-                return xml_print_ns(ctx, mod->ns, (prefix_opts & LYXML_PREFIX_DEFAULT) ? NULL : prefix->id, prefix_opts);
+                return xml_print_ns(ctx, mod->ns, (prefix_opts & LYXML_PREFIX_DEFAULT) ? NULL : name->prefix, prefix_opts);
             }
         }
         break;
@@ -263,9 +263,9 @@
 
     LY_LIST_FOR(node->attr, attr) {
         pref = NULL;
-        if (attr->prefix.id) {
+        if (attr->name.prefix) {
             /* print attribute namespace */
-            pref = xml_print_ns_opaq(ctx, attr->format, &attr->prefix, 0);
+            pref = xml_print_ns_opaq(ctx, attr->format, &attr->name, 0);
         }
 
         /* print namespaces connected with the value's prefixes */
@@ -274,7 +274,7 @@
         }
 
         /* print the attribute with its prefix and value */
-        ly_print_(ctx->out, " %s%s%s=\"%s\"", pref ? pref : "", pref ? ":" : "", attr->name, attr->value);
+        ly_print_(ctx->out, " %s%s%s=\"%s\"", pref ? pref : "", pref ? ":" : "", attr->name.name, attr->value);
     }
 
     return LY_SUCCESS;
@@ -284,10 +284,10 @@
 xml_print_opaq_open(struct xmlpr_ctx *ctx, const struct lyd_node_opaq *node)
 {
     /* print node name */
-    ly_print_(ctx->out, "%*s<%s", INDENT, node->name);
+    ly_print_(ctx->out, "%*s<%s", INDENT, node->name.name);
 
     /* print default namespace */
-    xml_print_ns_opaq(ctx, node->format, &node->prefix, LYXML_PREFIX_DEFAULT);
+    xml_print_ns_opaq(ctx, node->format, &node->name, LYXML_PREFIX_DEFAULT);
 
     /* print attributes */
     LY_CHECK_RET(xml_print_attr(ctx, node));
@@ -479,9 +479,9 @@
         }
         LEVEL_DEC;
 
-        ly_print_(ctx->out, "%*s</%s>%s", INDENT, node->name, DO_FORMAT ? "\n" : "");
+        ly_print_(ctx->out, "%*s</%s>%s", INDENT, node->name.name, DO_FORMAT ? "\n" : "");
     } else if (node->value[0]) {
-        ly_print_(ctx->out, "</%s>%s", node->name, DO_FORMAT ? "\n" : "");
+        ly_print_(ctx->out, "</%s>%s", node->name.name, DO_FORMAT ? "\n" : "");
     } else {
         /* no value or children */
         ly_print_(ctx->out, "/>%s", DO_FORMAT ? "\n" : "");
diff --git a/src/tree_data.c b/src/tree_data.c
index 4611953..e416666 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -684,13 +684,13 @@
     LY_CHECK_ERR_GOTO(!opaq, LOGMEM(ctx); ret = LY_EMEM, finish);
 
     opaq->prev = (struct lyd_node *)opaq;
-    LY_CHECK_GOTO(ret = lydict_insert(ctx, name, name_len, &opaq->name), finish);
+    LY_CHECK_GOTO(ret = lydict_insert(ctx, name, name_len, &opaq->name.name), finish);
 
     if (pref_len) {
-        LY_CHECK_GOTO(ret = lydict_insert(ctx, prefix, pref_len, &opaq->prefix.id), finish);
+        LY_CHECK_GOTO(ret = lydict_insert(ctx, prefix, pref_len, &opaq->name.prefix), finish);
     }
     if (module_key_len) {
-        LY_CHECK_GOTO(ret = lydict_insert(ctx, module_key, module_key_len, &opaq->prefix.module_ns), finish);
+        LY_CHECK_GOTO(ret = lydict_insert(ctx, module_key, module_key_len, &opaq->name.module_ns), finish);
     }
     if (dynamic && *dynamic) {
         LY_CHECK_GOTO(ret = lydict_insert_zc(ctx, (char *)value, &opaq->value), finish);
@@ -1012,16 +1012,16 @@
 
     switch (attr->format) {
     case LY_PREF_XML:
-        mod = ly_ctx_get_module_implemented_ns(ctx, attr->prefix.module_ns);
+        mod = ly_ctx_get_module_implemented_ns(ctx, attr->name.module_ns);
         if (!mod) {
-            LOGERR(ctx, LY_EINVAL, "Module with namespace \"%s\" not found.", attr->prefix.module_ns);
+            LOGERR(ctx, LY_EINVAL, "Module with namespace \"%s\" not found.", attr->name.module_ns);
             return LY_ENOTFOUND;
         }
         break;
     case LY_PREF_JSON:
-        mod = ly_ctx_get_module_implemented(ctx, attr->prefix.module_name);
+        mod = ly_ctx_get_module_implemented(ctx, attr->name.module_name);
         if (!mod) {
-            LOGERR(ctx, LY_EINVAL, "Module \"%s\" not found.", attr->prefix.module_name);
+            LOGERR(ctx, LY_EINVAL, "Module \"%s\" not found.", attr->name.module_name);
             return LY_ENOTFOUND;
         }
         break;
@@ -1029,7 +1029,7 @@
         LOGINT_RET(ctx);
     }
 
-    return lyd_create_meta(parent, meta, mod, attr->name, strlen(attr->name), attr->value, strlen(attr->value),
+    return lyd_create_meta(parent, meta, mod, attr->name.name, strlen(attr->name.name), attr->value, strlen(attr->value),
             NULL, attr->format, attr->val_prefix_data, attr->hints, clear_dflt, NULL);
 }
 
@@ -2242,12 +2242,12 @@
     at = calloc(1, sizeof *at);
     LY_CHECK_ERR_RET(!at, LOGMEM(ctx); ly_free_prefix_data(format, val_prefix_data), LY_EMEM);
 
-    LY_CHECK_GOTO(ret = lydict_insert(ctx, name, name_len, &at->name), finish);
+    LY_CHECK_GOTO(ret = lydict_insert(ctx, name, name_len, &at->name.name), finish);
     if (prefix_len) {
-        LY_CHECK_GOTO(ret = lydict_insert(ctx, prefix, prefix_len, &at->prefix.id), finish);
+        LY_CHECK_GOTO(ret = lydict_insert(ctx, prefix, prefix_len, &at->name.prefix), finish);
     }
     if (module_key_len) {
-        LY_CHECK_GOTO(ret = lydict_insert(ctx, module_key, module_key_len, &at->prefix.module_ns), finish);
+        LY_CHECK_GOTO(ret = lydict_insert(ctx, module_key, module_key_len, &at->name.module_ns), finish);
     }
 
     if (dynamic && *dynamic) {
@@ -2319,7 +2319,8 @@
     if (!node1->schema) {
         opaq1 = (struct lyd_node_opaq *)node1;
         opaq2 = (struct lyd_node_opaq *)node2;
-        if ((opaq1->name != opaq2->name) || (opaq1->format != opaq2->format) || (opaq1->prefix.module_ns != opaq2->prefix.module_ns)) {
+        if ((opaq1->name.name != opaq2->name.name) || (opaq1->format != opaq2->format) ||
+                (opaq1->name.module_ns != opaq2->name.module_ns)) {
             return LY_ENOT;
         }
         switch (opaq1->format) {
@@ -2572,12 +2573,12 @@
                 LY_CHECK_GOTO(ret = lyd_dup_r(child, dup, NULL, options, NULL), error);
             }
         }
-        LY_CHECK_GOTO(ret = lydict_insert(LYD_CTX(node), orig->name, 0, &opaq->name), error);
+        LY_CHECK_GOTO(ret = lydict_insert(LYD_CTX(node), orig->name.name, 0, &opaq->name.name), error);
         opaq->format = orig->format;
-        if (orig->prefix.id) {
-            LY_CHECK_GOTO(ret = lydict_insert(LYD_CTX(node), orig->prefix.id, 0, &opaq->prefix.id), error);
+        if (orig->name.prefix) {
+            LY_CHECK_GOTO(ret = lydict_insert(LYD_CTX(node), orig->name.prefix, 0, &opaq->name.prefix), error);
         }
-        LY_CHECK_GOTO(ret = lydict_insert(LYD_CTX(node), orig->prefix.module_ns, 0, &opaq->prefix.module_ns), error);
+        LY_CHECK_GOTO(ret = lydict_insert(LYD_CTX(node), orig->name.module_ns, 0, &opaq->name.module_ns), error);
         if (orig->val_prefix_data) {
             ret = ly_dup_prefix_data(LYD_CTX(node), opaq->format, orig->val_prefix_data, &opaq->val_prefix_data);
             LY_CHECK_GOTO(ret, error);
@@ -3070,7 +3071,8 @@
             }
 
             /* realloc string */
-            len = 1 + (mod ? strlen(mod->name) + 1 : 0) + (iter->schema ? strlen(iter->schema->name) : strlen(((struct lyd_node_opaq *)iter)->name));
+            len = 1 + (mod ? strlen(mod->name) + 1 : 0) + (iter->schema ? strlen(iter->schema->name) :
+                    strlen(((struct lyd_node_opaq *)iter)->name.name));
             rc = lyd_path_str_enlarge(&buffer, &buflen, bufused + len, is_static);
             if (rc != LY_SUCCESS) {
                 break;
@@ -3078,7 +3080,7 @@
 
             /* print next node */
             bufused += sprintf(buffer + bufused, "/%s%s%s", mod ? mod->name : "", mod ? ":" : "",
-                    iter->schema ? iter->schema->name : ((struct lyd_node_opaq *)iter)->name);
+                    iter->schema ? iter->schema->name : ((struct lyd_node_opaq *)iter)->name.name);
 
             /* do not always print the last (first) predicate */
             if (iter->schema && ((depth > 1) || (pathtype == LYD_PATH_LOG))) {
diff --git a/src/tree_data.h b/src/tree_data.h
index 2462c84..9b74f5c 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -477,13 +477,14 @@
  *
  * The union is used as a reference to the data's module and according to the format, it can be used as a key for
  * ::ly_ctx_get_module_implemented_ns() or ::ly_ctx_get_module_implemented(). While the module reference is always present,
- * the id member can be omitted in case it is not present in the source data as a reference to the default namespace.
+ * the prefix member can be omitted in case it is not present in the source data as a reference to the default module/namespace.
  */
-struct ly_prefix {
-    const char *id;               /**< identifier used in the qualified name of the item to reference data node namespace */
+struct ly_opaq_name {
+    const char *name;             /**< node name, without prefix if any was defined */
+    const char *prefix;           /**< identifier used in the qualified name as the prefix, can be NULL */
     union {
-        const char *module_ns;    /**< namespace of the module where the data are supposed to belongs to, used for LYD_XML format. */
-        const char *module_name;  /**< name of the module where the data are supposed to belongs to, used for LYD_JSON format. */
+        const char *module_ns;    /**< format ::LY_PREF_XML - XML namespace of the node element */
+        const char *module_name;  /**< format ::LY_PREF_JSON - (inherited) name of the module of the element */
     };
 };
 
@@ -493,8 +494,7 @@
 struct lyd_attr {
     struct lyd_node_opaq *parent;   /**< data node where the attribute is placed */
     struct lyd_attr *next;          /**< pointer to the next attribute */
-    const char *name;               /**< attribute name */
-    struct ly_prefix prefix;        /**< name prefix, it is stored because they are a real pain to generate properly */
+    struct ly_opaq_name name;       /**< attribute name with module information */
     const char *value;              /**< attribute value */
     LY_PREFIX_FORMAT format;        /**< format of the attribute and any prefixes, ::LY_PREF_XML or ::LY_PREF_JSON */
     void *val_prefix_data;          /**< format-specific prefix data (see ::ly_resolve_prefix()) */
@@ -720,8 +720,7 @@
 
     struct lyd_node *child;         /**< pointer to the child node (compatible with ::lyd_node_inner) */
 
-    const char *name;               /**< node name */
-    struct ly_prefix prefix;        /**< name prefix */
+    struct ly_opaq_name name;       /**< node name with module information */
     const char *value;              /**< original value */
     LY_PREFIX_FORMAT format;        /**< format of the node and any prefixes, ::LY_PREF_XML or ::LY_PREF_JSON */
     void *val_prefix_data;          /**< format-specific prefix data (see ::ly_resolve_prefix()) */
diff --git a/src/tree_data_free.c b/src/tree_data_free.c
index 828a152..274897a 100644
--- a/src/tree_data_free.c
+++ b/src/tree_data_free.c
@@ -116,10 +116,10 @@
         iter = iter->next;
 
         ly_free_prefix_data(attr->format, attr->val_prefix_data);
-        FREE_STRING(ctx, attr->name);
+        FREE_STRING(ctx, attr->name.name);
+        FREE_STRING(ctx, attr->name.prefix);
+        FREE_STRING(ctx, attr->name.module_ns);
         FREE_STRING(ctx, attr->value);
-        FREE_STRING(ctx, attr->prefix.id);
-        FREE_STRING(ctx, attr->prefix.module_ns);
         free(attr);
     }
 }
@@ -157,9 +157,9 @@
             lyd_free_subtree(iter, 0);
         }
 
-        FREE_STRING(LYD_CTX(opaq), opaq->name);
-        FREE_STRING(LYD_CTX(opaq), opaq->prefix.id);
-        FREE_STRING(LYD_CTX(opaq), opaq->prefix.module_ns);
+        FREE_STRING(LYD_CTX(opaq), opaq->name.name);
+        FREE_STRING(LYD_CTX(opaq), opaq->name.prefix);
+        FREE_STRING(LYD_CTX(opaq), opaq->name.module_ns);
         FREE_STRING(LYD_CTX(opaq), opaq->value);
         ly_free_prefix_data(opaq->format, opaq->val_prefix_data);
     } else if (node->schema->nodetype & LYD_NODE_INNER) {