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 {