I have the following YANG model:
list machines {
key "name";
leaf "name" {
type string;
}
leaf link {
type leafref {
path "../name";
}
}
}
Suppose there are three elements in the list:
"machines" : [
{ "name": "a" },
{ "name": "b" },
{ "name": "c" }
]
If I want to set "link"
for element b
, the valid values for "link"
are "a", "b", "c"
or just "b"
?
I didn't find answer in RFC7950. And in pyangbind, only "b"
can be set. But I'm not sure that is the right behavior.
If ../name
here can only reference "b"
, what is the correct path to reference "a", "b", "c"
, that is, all names of list elements?
If ../name
here can reference "a", "b", "c"
, what is the correct path to reference only "b"
?
Thanks
This is what RFC7950 says for lists:
Despite your JSON encoded instance document seemingly suggesting that only one instance of the
machines
list exists within it, there are actually three list instances. The name you chose for the list deepens this confusion, as the recommended name for a list definition would be "machine". An enveloping container would take the plural form of the name.In XML encoding, the above becomes more obvious.
A leafref path expression is a subset of XPath. The same rules apply, you are just limited in what you can select with the expression - it is intended to select one or more leaf instances. XPath always works on a tree of objects and this tree is (somewhat awkwardly) defined in RFC7950 - the document refers to this tree as the
accessible tree
and it consists of instantiated data nodes (subset of a data tree). This is described in Section 6.4.1.In addition to the accessible tree, a context node is also important (relative expressions refer to it implicitly). Here is what RFC7950 says about the context node in your example.
This would be the
link
instance in your case, a sibling to thename
instance with valueb
. Here's a quick pseudo- data tree:The expression first proceeds to select the parent of
link
. There is always only one parent for any given data node instance and in your case that would be the list instance that has both siblings mentioned before as children (machines[2]
). The expression then proceeds to select children that have aname
name, which is the instance ofname
with valueb
.This means the only valid value for your
link
node isb
. This only applies to your specific example.Use an absolute expression or go one parent further, then back again:
//machines/name
(replace the//
with an absolute path tomachines
)../../machines/name
Both of these will then first select all instantiated
machines
.Note: this is just how XPath works. The other alternative would apply if RFC7950 text would say "there is only one list instance with multiple entries" or something along those lines.