printer & parser json BUGFIX anyxml node

Anyxml was processed exactly as anydata,
which is completely wrong and is more
similar to leaf.
Refs #1762
diff --git a/src/parser_json.c b/src/parser_json.c
index 146b37a..355b544 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -20,6 +20,7 @@
 #include <string.h>
 
 #include "common.h"
+#include "compat.h"
 #include "context.h"
 #include "dict.h"
 #include "in_internal.h"
@@ -1160,14 +1161,17 @@
         enum LYJSON_PARSER_STATUS *status, struct lyd_node **node)
 {
     LY_ERR ret;
-    uint32_t type_hints = 0;
-    uint32_t prev_parse_opts, prev_int_opts;
+    uint32_t type_hints = 0, prev_parse_opts, prev_int_opts;
+    char *val;
     struct lyd_node *tree = NULL;
 
     ret = lydjson_data_check_opaq(lydctx, snode, &type_hints);
     if (ret == LY_SUCCESS) {
         assert(snode->nodetype & (LYD_NODE_TERM | LYD_NODE_INNER | LYD_NODE_ANY));
         if (snode->nodetype & LYD_NODE_TERM) {
+            LY_CHECK_RET((*status != LYJSON_ARRAY) && (*status != LYJSON_NUMBER) && (*status != LYJSON_STRING) &&
+                    (*status != LYJSON_FALSE) && (*status != LYJSON_TRUE) && (*status != LYJSON_NULL), LY_EINVAL);
+
             /* create terminal node */
             ret = lyd_parser_create_term((struct lyd_ctx *)lydctx, snode, lydctx->jsonctx->value,
                     lydctx->jsonctx->value_len, &lydctx->jsonctx->dynamic, LY_VALUE_JSON, NULL,
@@ -1183,9 +1187,32 @@
                 assert(*status == LYJSON_ARRAY_CLOSED);
             }
             LY_CHECK_RET(lyjson_ctx_next(lydctx->jsonctx, status));
+        } else if (snode->nodetype == LYS_ANYXML) {
+            LY_CHECK_RET((*status != LYJSON_STRING) && (*status != LYJSON_NULL), LY_EINVAL);
+
+            /* create anyxml node */
+            if (*status == LYJSON_NULL) {
+                ret = lyd_create_any(snode, NULL, LYD_ANYDATA_STRING, 1, node);
+                LY_CHECK_RET(ret);
+            } else if (lydctx->jsonctx->dynamic) {
+                ret = lyd_create_any(snode, lydctx->jsonctx->value, LYD_ANYDATA_STRING, 1, node);
+                LY_CHECK_RET(ret);
+                lydctx->jsonctx->dynamic = 0;
+            } else {
+                val = strndup(lydctx->jsonctx->value, lydctx->jsonctx->value_len);
+                LY_CHECK_ERR_RET(!val, LOGMEM(lydctx->jsonctx->ctx), LY_EMEM);
+                ret = lyd_create_any(snode, val, LYD_ANYDATA_STRING, 1, node);
+                if (ret) {
+                    free(val);
+                    return ret;
+                }
+            }
+
+            /* move JSON parser */
+            LY_CHECK_RET(lyjson_ctx_next(lydctx->jsonctx, status));
         } else if (snode->nodetype & LYD_NODE_INNER) {
             /* create inner node */
-            LY_CHECK_RET(*status != LYJSON_OBJECT && *status != LYJSON_OBJECT_EMPTY, LY_EINVAL);
+            LY_CHECK_RET((*status != LYJSON_OBJECT) && (*status != LYJSON_OBJECT_EMPTY), LY_EINVAL);
 
             ret = lyd_create_inner(snode, node);
             LY_CHECK_RET(ret);
@@ -1193,7 +1220,7 @@
             LOG_LOCSET(snode, *node, NULL, NULL);
 
             /* process children */
-            while (*status != LYJSON_OBJECT_CLOSED && *status != LYJSON_OBJECT_EMPTY) {
+            while ((*status != LYJSON_OBJECT_CLOSED) && (*status != LYJSON_OBJECT_EMPTY)) {
                 ret = lydjson_subtree_r(lydctx, *node, lyd_node_child_p(*node), NULL);
                 LY_CHECK_ERR_RET(ret, LOG_LOCBACK(1, 1, 0, 0), ret);
                 *status = lyjson_ctx_status(lydctx->jsonctx, 0);
@@ -1225,9 +1252,9 @@
             /* move JSON parser */
             ret = lyjson_ctx_next(lydctx->jsonctx, status);
             LY_CHECK_RET(ret);
-        } else if (snode->nodetype & LYD_NODE_ANY) {
+        } else if (snode->nodetype == LYS_ANYDATA) {
             /* create any node */
-            LY_CHECK_RET(*status != LYJSON_OBJECT && *status != LYJSON_OBJECT_EMPTY, LY_EINVAL);
+            LY_CHECK_RET((*status != LYJSON_OBJECT) && (*status != LYJSON_OBJECT_EMPTY), LY_EINVAL);
 
             /* parse any data tree with correct options */
             /* first backup the current options and then make the parser to process data as opaq nodes */
@@ -1238,7 +1265,7 @@
             lydctx->int_opts |= LYD_INTOPT_ANY | LYD_INTOPT_WITH_SIBLINGS;
 
             /* process the anydata content */
-            while (*status != LYJSON_OBJECT_CLOSED && *status != LYJSON_OBJECT_EMPTY) {
+            while ((*status != LYJSON_OBJECT_CLOSED) && (*status != LYJSON_OBJECT_EMPTY)) {
                 ret = lydjson_subtree_r(lydctx, NULL, &tree, NULL);
                 LY_CHECK_RET(ret);
                 *status = lyjson_ctx_status(lydctx->jsonctx, 0);
@@ -1402,7 +1429,7 @@
         case LYS_RPC:
         case LYS_ANYDATA:
         case LYS_ANYXML:
-            if (snode->nodetype == LYS_LEAF) {
+            if (snode->nodetype & (LYS_LEAF | LYS_ANYXML)) {
                 if (status == LYJSON_ARRAY) {
                     expected = "name/[null]";
                 } else {
diff --git a/src/printer_json.c b/src/printer_json.c
index 6b2ee02..7c251a1 100644
--- a/src/printer_json.c
+++ b/src/printer_json.c
@@ -518,21 +518,27 @@
 }
 
 /**
- * @brief Print anydata data node including its metadata.
+ * @brief Print anydata/anyxml content.
  *
  * @param[in] ctx JSON printer context.
  * @param[in] any Anydata node to print.
  * @return LY_ERR value.
  */
 static LY_ERR
-json_print_anydata(struct jsonpr_ctx *ctx, struct lyd_node_any *any)
+json_print_any_content(struct jsonpr_ctx *ctx, struct lyd_node_any *any)
 {
     LY_ERR ret = LY_SUCCESS;
     struct lyd_node *iter;
     uint32_t prev_opts, prev_lo;
 
+    /* anyxml - printed as name/value pair;
+     * anydata - printed as an object */
+
     if (!any->value.tree) {
         /* no content */
+        if (any->schema->nodetype == LYS_ANYXML) {
+            ly_print_(ctx->out, "null");
+        }
         return LY_SUCCESS;
     }
 
@@ -556,6 +562,11 @@
 
     switch (any->value_type) {
     case LYD_ANYDATA_DATATREE:
+        if (any->schema->nodetype == LYS_ANYXML) {
+            /* print always as a string */
+            ly_print_(ctx->out, "\"%s", DO_FORMAT ? "\n" : "");
+        }
+
         /* close opening tag and print data */
         prev_opts = ctx->options;
         ctx->options &= ~LYD_PRINT_WITHSIBLINGS;
@@ -566,28 +577,42 @@
         }
 
         ctx->options = prev_opts;
+
+        if (any->schema->nodetype == LYS_ANYXML) {
+            /* terminate the string */
+            ly_print_(ctx->out, "\"");
+        }
         break;
     case LYD_ANYDATA_JSON:
         /* print without escaping special characters */
-        if (!any->value.str[0]) {
-            return LY_SUCCESS;
+        if (any->schema->nodetype == LYS_ANYXML) {
+            /* print as a string */
+            ly_print_(ctx->out, "\"%s\"", any->value.str);
+        } else if (any->value.str[0]) {
+            /* print with indent */
+            ly_print_(ctx->out, "%*s%s", INDENT, any->value.str);
         }
-        ly_print_(ctx->out, "%*s%s", INDENT, any->value.str);
         break;
     case LYD_ANYDATA_STRING:
     case LYD_ANYDATA_XML:
+        if (any->schema->nodetype == LYS_ANYXML) {
+            /* print as a string */
+            ly_print_(ctx->out, "\"%s\"", any->value.str);
+            break;
+        }
+    /* fallthrough */
     case LYD_ANYDATA_LYB:
         /* JSON and LYB format is not supported */
         LOGWRN(ctx->ctx, "Unable to print anydata content (type %d) as XML.", any->value_type);
-        return LY_SUCCESS;
+        break;
     }
 
     return LY_SUCCESS;
 }
 
 /**
- * @brief Print content of a single container/list data node including its metadata.
- * The envelope specific to container and list are expected to be printed by the caller.
+ * @brief Print content of a single container/list/anydata data node including its metadata.
+ * The envelope specific to nodes are expected to be printed by the caller.
  *
  * @param[in] ctx JSON printer context.
  * @param[in] node Data node to print.
@@ -629,7 +654,7 @@
         }
     } else {
         /* anydata */
-        json_print_anydata(ctx, (struct lyd_node_any *)node);
+        json_print_any_content(ctx, (struct lyd_node_any *)node);
     }
 
     LEVEL_DEC;
@@ -660,6 +685,26 @@
 }
 
 /**
+ * @brief Print anyxml data node including its metadata.
+ *
+ * @param[in] ctx JSON printer context.
+ * @param[in] node Data node to print.
+ * @return LY_ERR value.
+ */
+static int
+json_print_anyxml(struct jsonpr_ctx *ctx, const struct lyd_node *node)
+{
+    LY_CHECK_RET(json_print_member(ctx, node, 0));
+    LY_CHECK_RET(json_print_any_content(ctx, (struct lyd_node_any *)node));
+    LEVEL_PRINTED;
+
+    /* print attributes as sibling */
+    json_print_attributes(ctx, node, 0);
+
+    return LY_SUCCESS;
+}
+
+/**
  * @brief Check whether a node is the last printed instance of a (leaf-)list.
  *
  * @param[in] ctx JSON printer context.
@@ -867,6 +912,7 @@
         case LYS_RPC:
         case LYS_ACTION:
         case LYS_NOTIF:
+        case LYS_ANYDATA:
         case LYS_CONTAINER:
             LY_CHECK_RET(json_print_container(ctx, node));
             break;
@@ -878,8 +924,7 @@
             LY_CHECK_RET(json_print_leaf_list(ctx, node));
             break;
         case LYS_ANYXML:
-        case LYS_ANYDATA:
-            LY_CHECK_RET(json_print_container(ctx, node));
+            LY_CHECK_RET(json_print_anyxml(ctx, node));
             break;
         default:
             LOGINT(node->schema->module->ctx);