Savvas Parastatidis
Savvas Parastatidis

Reputation: 802

Only allow unique keys in seperate lists in YANG Model

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?

Upvotes: 1

Views: 1119

Answers (1)

predi
predi

Reputation: 5928

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)

Upvotes: 0

Related Questions