parser data UPDATE allow action element for actions

Fixes cesnet/netopeer2#1416
diff --git a/src/parser_xml.c b/src/parser_xml.c
index 054e01a..db760b1 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -1147,7 +1147,8 @@
 {
     LY_ERR r, rc = LY_SUCCESS;
     struct lyd_xml_ctx *lydctx;
-    ly_bool parsed_data_nodes = 0;
+    ly_bool parsed_data_nodes = 0, close_elem = 0;
+    struct lyd_node *act = NULL;
     enum LYXML_PARSER_STATUS status;
 
     assert(ctx && in && lydctx_p);
@@ -1167,6 +1168,14 @@
     /* find the operation node if it exists already */
     LY_CHECK_GOTO(rc = lyd_parser_find_operation(parent, int_opts, &lydctx->op_node), cleanup);
 
+    if ((int_opts & LYD_INTOPT_RPC) && (int_opts & LYD_INTOPT_ACTION)) {
+        /* can be either, try to parse "action" */
+        if (!lydxml_envelope(lydctx->xmlctx, "action", "urn:ietf:params:xml:ns:yang:1", 0, &act)) {
+            close_elem = 1;
+            int_opts &= ~LYD_INTOPT_RPC;
+        }
+    }
+
     /* parse XML data */
     while (lydctx->xmlctx->status == LYXML_ELEMENT) {
         r = lydxml_subtree_r(lydctx, parent, first_p, parsed);
@@ -1179,6 +1188,19 @@
         }
     }
 
+    /* close an opened element */
+    if (close_elem) {
+        if (lydctx->xmlctx->status != LYXML_ELEM_CLOSE) {
+            assert(lydctx->xmlctx->status == LYXML_ELEMENT);
+            LOGVAL(lydctx->xmlctx->ctx, LYVE_SYNTAX, "Unexpected child element \"%.*s\".",
+                    (int)lydctx->xmlctx->name_len, lydctx->xmlctx->name);
+            rc = LY_EVALID;
+            goto cleanup;
+        }
+
+        LY_CHECK_GOTO(rc = lyxml_ctx_next(lydctx->xmlctx), cleanup);
+    }
+
     /* check final state */
     if ((int_opts & LYD_INTOPT_NO_SIBLINGS) && (lydctx->xmlctx->status == LYXML_ELEMENT)) {
         LOGVAL(ctx, LYVE_SYNTAX, "Unexpected sibling node.");
@@ -1211,6 +1233,7 @@
     assert(!(parse_opts & LYD_PARSE_ONLY) || (!lydctx->node_types.count && !lydctx->meta_types.count &&
             !lydctx->node_when.count));
 
+    lyd_free_tree(act);
     if (rc && (!(lydctx->val_opts & LYD_VALIDATE_MULTI_ERROR) || (rc != LY_EVALID))) {
         lyd_xml_ctx_free((struct lyd_ctx *)lydctx);
     } else {