libyang icon indicating copy to clipboard operation
libyang copied to clipboard

In libyang-2.0.194, how to find a match and validate a value with leaf reference node in union at a given XPATH?

Open feanis opened this issue 3 years ago • 6 comments

Hi,

There are lots of internal changes with libyang-2.0.194 in contrast of libyang-1-0-225, I had an working function(lyd_node_leafref_match_in_union) with libyang-1 to check if the value matches with leaf reference nodes in union at a given XPATH, as shown below.

// Using libyang-1-0-225, Check if value matches with leafref node in union
int lyd_node_leafref_match_in_union(struct lys_module *module, const char *xpath, const char *value)
{
        struct ly_set *set = NULL;
        struct lys_node *node = NULL;
        int idx = 0;
        struct lys_node_leaflist* lNode;
        if (module == NULL)
        {
                return -1;
        }
        set = lys_find_path(module, NULL, xpath);
        if (set == NULL || set->number == 0) {
                return  -1;
        }
        node = set->set.s[0];
        ly_set_free(set);
        //Now check if it matches with any leafref node
        lNode = (struct lys_node_leaflist*)node;
        for (idx = 0; idx < lNode->type.info.uni.count; idx++)
        {
                if (lNode->type.info.uni.types[idx].base != LY_TYPE_LEAFREF)
                {
                        //Look for leafref type only
                        continue;
                }
                if (0 == lyd_validate_value((struct lys_node*)
                    lNode->type.info.uni.types[idx].info.lref.target, value))
                {
                        return 0;
                }
        }
        return -1;
}

Please help me to implement the above functionality with Libyang-2.0.194.

Thanks & Regards, Feanis Das

feanis avatar Jul 05 '22 12:07 feanis

The most challenging task is getting the leafref target, which is no longer stored in the type. Once you get the schema node on the XPath, you should be able to get its leafref type. Call lyxp_get_expr(((struct lysc_type_leafref *)type)->path) to get the path to the target and then use it in target = lys_find_path(NULL, schema, path, 0) to get the target. Then you should be able to use lyd_value_validate() in the same way to validate the value.

michalvasko avatar Jul 14 '22 13:07 michalvasko

Hi, I'm commenting here because i found myself stuck with some similar problem. I was first using lys_find_xpath() to try to find the target, but I am having problems with prefix resolving (I might create another issue for that). I found this issue and tried to use lys_find_path(), but it won't work with relative path starting with ddots (like "../interface/name" ), as show in the RFC example.

when i use it: lys_find_path() calls ly_path_compile() which calls _ly_path_compile() with lref = 0. lref = 0 makes us unable to use relative path with ddots.

I also found ly_path_compile_leafref() but it's not usable in our case because we can't call lyxp_expr_parse() first, as it's not public. Moreover, the limit_access_tree = 1 might be problematic.

is there any solution here?

Haititi avatar Jul 22 '22 10:07 Haititi

I do not understand your use-case, exactly. If you have a leafref node, it is parsed and so you should be able to use ly_path_compile_leafref(). If not, then what exactly are you doing?

michalvasko avatar Jul 22 '22 11:07 michalvasko

Well, I have a schema node of type LYS_LEAF, so i cast it to lysc_node_leaf and retrieve the lysc_type type. The type's basetype is LY_TYPE_LEAFREF so i casted it to lysc_type_leafref. From here i can retrieve the lyxp_expr* path. Then i did what you said : i called const char * xpath = lyxp_get_expr(((struct lysc_type_leafref *)type)->path), and i got the path "../interface/name" . I then called target = lys_find_path(NULL, schema, path, 0), but this fails (target is NULL), because lys_find_path() uses ly_path_compile() internally, which does not support leafref nodes.

So i try to understand which method should be used here, as the one you gave in the previous comment is not working.

Moreover, the ly_path_compile_leafref() API is not public, we can't use it.

Haititi avatar Jul 22 '22 14:07 Haititi

I see. Well, you can always use lys_find_xpath() that accepts all the XPaths.

michalvasko avatar Jul 25 '22 08:07 michalvasko

Thanks for your reply. I will create another issue then for the problem i'm encountering.

Haititi avatar Jul 25 '22 10:07 Haititi