Skip to content

Commit

Permalink
Fix issue with xpath query
Browse files Browse the repository at this point in the history
A "malformed-message" error is returned if an xpath query of the type
"/oc-sys:system/processes/process/state/name"
is made, where the xpath conists of a filter to match on the
leaf-nodes ("name") associated with multiple list entries("process").
This is because no matching apteryx-xml schema is found for this
type of XPATH query.
The proposed change fixes this issue.
  • Loading branch information
psiyengar committed May 9, 2024
1 parent b2252bb commit 05dc665
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 14 deletions.
1 change: 1 addition & 0 deletions apteryx-xml.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ typedef enum
SCH_F_FILTER_RDEPTH = (1 << 14), /* Set filter based on depth value */
} sch_flags;
GNode *sch_path_to_gnode (sch_instance * instance, sch_node * schema, const char * path, int flags, sch_node ** rschema);
GNode *sch_path_to_gnode_netconf (sch_instance * instance, sch_node * schema, const char * path, int flags, sch_node ** rschema, sch_node ** vschema);
bool sch_query_to_gnode (sch_instance * instance, sch_node * schema, GNode *parent, const char * query, int flags, int *rflags);
bool sch_traverse_tree (sch_instance * instance, sch_node * schema, GNode * node, int flags, int rdepth);
GNode *sch_path_to_query (sch_instance * instance, sch_node * schema, const char * path, int flags); //DEPRECATED
Expand Down
78 changes: 64 additions & 14 deletions schema.c
Original file line number Diff line number Diff line change
Expand Up @@ -2609,7 +2609,7 @@ bool sch_query_to_gnode (sch_instance * instance, sch_node * schema, GNode *pare
}

static GNode *
_sch_path_to_gnode (sch_instance * instance, sch_node ** rschema, xmlNs *ns, const char *path, int flags, int depth)
_sch_path_to_gnode (sch_instance * instance, sch_node ** rschema, sch_node ** vschema, xmlNs *ns, const char *path, int flags, int depth)
{
sch_node *schema = rschema && *rschema ? *rschema : xmlDocGetRootElement (instance->doc);
const char *next = NULL;
Expand Down Expand Up @@ -2681,6 +2681,27 @@ _sch_path_to_gnode (sch_instance * instance, sch_node ** rschema, xmlNs *ns, con
}
}

if ((flags & SCH_F_XPATH) && schema && vschema && *vschema == NULL && sch_is_list (schema))
{
/* Check for a schema list that has a parent that has skipped down
* to the next schema level down without a list item selector */
sch_node *parent = sch_node_parent (schema);
if (parent)
{
GList *path_list = NULL;
char *__next = g_strdup_printf ("/%s", name);
bool found = sch_node_find_name (instance, ns, parent, __next, flags, &path_list);
g_list_free_full (path_list, g_free);
g_free (__next);

if (found)
{
*vschema = parent;
goto exit;
}
}
}

/* Find schema node */
if (!schema || sch_is_proxy (schema))
schema = xmlDocGetRootElement (instance->doc);
Expand Down Expand Up @@ -2790,12 +2811,15 @@ _sch_path_to_gnode (sch_instance * instance, sch_node ** rschema, xmlNs *ns, con

if (next)
{
node = _sch_path_to_gnode (instance, &schema, ns, next, flags, depth + 1);
node = _sch_path_to_gnode (instance, &schema, vschema, ns, next, flags, depth + 1);
if (!node)
{
free ((void *)rnode->data);
g_node_destroy (rnode);
rnode = NULL;
if (!vschema || !*vschema)
{
free ((void *)rnode->data);
g_node_destroy (rnode);
rnode = NULL;
}
goto exit;
}
g_node_prepend (child ? : rnode, node);
Expand All @@ -2810,23 +2834,49 @@ _sch_path_to_gnode (sch_instance * instance, sch_node ** rschema, xmlNs *ns, con
return rnode;
}

static void
_modify_path (const char* xpath, char ** path)
{
if (path)
{
char **split = g_strsplit (xpath, "//", -1);
*path = g_strjoinv ("/*/", split);
g_strfreev (split);
}
}

GNode *
sch_path_to_gnode (sch_instance * instance, sch_node * schema, const char *path, int flags, sch_node ** rschema)
{
GNode *node;
char *_path = NULL;

if ((flags & SCH_F_XPATH))
if ((flags & SCH_F_XPATH) && (strstr (path, "//")))
{
if (strstr (path, "//"))
{
char **split = g_strsplit (path, "//", -1);
_path = g_strjoinv ("/*/", split);
g_strfreev (split);
_modify_path (path, &_path);
if (_path)
path = _path;
}
}
node = _sch_path_to_gnode (instance, rschema, NULL, path, flags, 0);
node = _sch_path_to_gnode (instance, rschema, NULL, NULL, path, flags, 0);
g_free (_path);

return node;
}

GNode *
sch_path_to_gnode_netconf (sch_instance * instance, sch_node * schema, const char *path, int flags, sch_node ** rschema, sch_node ** vschema)
{
GNode *node;
char *_path = NULL;

if ((flags & SCH_F_XPATH) && (strstr (path, "//")))
{
_modify_path (path, &_path);
if (_path)
path = _path;
}

node = _sch_path_to_gnode (instance, rschema, vschema, NULL, path, flags, 0);
g_free (_path);

return node;
Expand All @@ -2850,7 +2900,7 @@ sch_path_to_query (sch_instance * instance, sch_node * schema, const char *path,

/* Parse the path first */
tl_error = SCH_E_SUCCESS;
root = _sch_path_to_gnode (instance, &schema, NULL, path, flags, 0);
root = _sch_path_to_gnode (instance, &schema, NULL, NULL, path, flags, 0);
if (!root || !schema)
{
free (_path);
Expand Down

0 comments on commit 05dc665

Please sign in to comment.