1

My yang model has two same-level lists. I need the elements on both lists to be unique. Not unique within each list, but unique in the union of the lists. Is there a way to define this with a must statement or something?

container parent {
    list a {
        key "name";
        leaf name {
            type string;
        }
        leaf something {
            type string;
        }
    }
    list b {
        key "name";
        leaf name {
            type string;
        }
        leaf something-else{
            type string;
        }
    }
}

So, how would I make sure that every element has a different name?

  • Your question is somewhat unclear. *Element name* uniqueness is achieved by a YANG modeler by specifying leaf names at design time. You probably want *element value* uniqueness. – predi Mar 04 '21 at 08:20
  • Yes, I was talking about the values of leaf name. Just a bad leaf naming for this example. – Savvas Parastatidis Mar 04 '21 at 12:36

1 Answers1

0

Assuming you need unique values of certain elements within a union between two lists, you can indeed achieve this using a must constraint.

(Also) assuming that you need unique values for something and something-else, you can put a must constraint on list b with a condition like this:

not(../a[something=current()/something-else])

So, values of something are not required to be unique across all instances of list a, values of something-else are not required to be unique across all instances of list b, but an intersection across distinct values of something and distinct values of something-else must be an empty set.

module a {
  yang-version 1.1;
  namespace "a:uri";
  prefix "a";

  container parent {
    list a {
        key "name";
        leaf name {
            type string;
        }
        leaf something {
            type string;
        }
    }
    list b {
        must "not(../a[something=current()/something-else])";
        key "name";
        leaf name {
            type string;
        }
        leaf something-else{
            type string;
        }
    }
  }
}

An example of an invalid document:

<?xml version="1.0" encoding="utf-8"?>
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <a1:parent xmlns:a1="a:uri">
    <a1:a>
      <a1:name>a-1</a1:name>
      <a1:something>foo</a1:something>
    </a1:a>
    <a1:a>
      <a1:name>a-2</a1:name>
      <a1:something>foo</a1:something>
    </a1:a>
    <a1:b>
      <a1:name>b-1</a1:name>
      <a1:something-else>bar</a1:something-else> 
    </a1:b>
    <a1:b>
      <a1:name>b-2</a1:name>
      <a1:something-else>foo</a1:something-else>
    </a1:b>
  </a1:parent>
</data>

Which would fail validation with something like: Error at (16:5): failed assert at "/nc:data/a1:parent/a1:b": Condition "not(../a1:a[a1:something=current()/a1:something-else])" must be true

Note that this is just one example of how you could approach your requirement. You could, for example, move my condition to the something-else leaf, which would then become something like this (did not test):

not(.=../../a/something)
predi
  • 5,528
  • 32
  • 60
  • Hey, your answer is working neatly. I just realized I have something more complex, but I don't want to open another question. How would your solution work if there were more than 2 lists in the union? – Savvas Parastatidis Mar 08 '21 at 10:17
  • @SavvasParastatidis, if you had an additional `list c` with a `leaf something-else-entirely` in it, you would need to add "&ed" conditions to both b and c lists: `not(../a[something=current()/something-else]) and not(../c[something-else-entirely=current()/something-else])` to "list b" and `not(../a[something=current()/something-else-entirely]) and not(../b[something-else=current()/something-else-entirely])` to "list c". Each new list would require an additional & condition in all of the lists (except the first one - `a`). Not ideal. Perhaps you need to rethink this model from scratch. – predi Mar 08 '21 at 11:23
  • Yes I have realized that it's pretty complicated. However, it's not entirely on my hands to design it, so I'm trying to figure out solutions before I propose something. – Savvas Parastatidis Mar 08 '21 at 13:49