title: How to use count() in must() clause in a YANG model?
body: <p>I tried to research this over the last few days but my research came up short, there seems not to be a lot of material out there on the use of the <strong>must()</strong> clause in a <strong>YANG</strong> model.</p>
  
  <p><strong>Background</strong></p>
  
  <p>I am trying to extend the NETCONF model of an I2RS YANG model (based on <a href="https://datatracker.ietf.org/doc/draft-clemm-i2rs-yang-network-topo/?include_text=1" rel="nofollow">IETF I2RS Data Model for Network Topologies</a>) with some customer-specific information. My model therefore augments the relevant parts of the model (shown in an abbreviated form here). Where I am stuck is formulating a proper way to implement some semantic contraints on the input data, specifically around the number of links that have a specific <strong>link-usage</strong>.
  pyang is used as the toolchain for the following discussion.</p>
  
  <p><strong>The augmenting YANG module</strong></p>
  
  <p>The abbreviated module looks like this:</p>
  
  <pre><code>module bsc-topology {
  yang-version 1;
  
  namespace "urn:TBD:params:xml:ns:yang:bsc:bsc-topology";
  
  prefix "bsc";
  
  import nodes {
      prefix "nd";
      revision-date 2015-03-09;
  }
  
  import network-topology {
      prefix "nt";
      revision-date 2015-03-09;
  }
  
  import ietf-inet-types {    
      prefix "inet";
  }
  
  organization "TBD";
  contact "TBD";
  
  revision "2015-03-11" {
      description "Initial revision";
      reference "TBD";
  }
  
  identity flag-identity {
      description "Base type for flags";
  }
  
  identity undefined-flag {
      base "flag-identity";
  }
  
  typedef bsc-link-service-type {
      type enumeration {
          enum "Ater" {
              value 1;
              description "This link describes the Ater topology";
          }
          enum "Gb" {
              value 2;
              description "This link describes the Gb topology";
          }
      }
  }
  
  typedef flag-type {
  
      type identityref {
          base "flag-identity";
      }
  }
  
  grouping ater-attributes {
      leaf prefix {
          type inet:ip-prefix;
      }
      leaf metric {
          type uint32;
      }
      leaf-list flag {
          type flag-type;
      }
  }
  
  grouping bsc-topology-type {
      container bsc-topology {
          presence "Indicates BSC Topology";
      }
  }
  
  grouping bsc-link-attributes {
      container bsc-link-attributes {
          leaf name {
              description "Link Name";
              type string;
          }
  
          leaf link-usage {
              type bsc-link-service-type;
  
              description "Type of Service described through this link (Ater or Gb)";
  
              must "boolean(count(../../../nd:link) = 1)";    
          }       
      }       
  } 
  
  
  augment "/nd:network/nd:network-types" {
      uses bsc-topology-type;
  }
  
  augment "/nd:network/nt:link" {
      when "/nd:network/nd:network-types/bsc-topology";
      uses bsc:bsc-link-attributes;
  }
  } 
  </code></pre>
  
  <p><strong>The input file</strong></p>
  
  <p>Trying to validate the following input:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
      &lt;config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"&gt;
        &lt;nd:network xmlns:nd="urn:TBD:params:xml:ns:yang:nodes"&gt;
          &lt;nd:network-id&gt;Test&lt;/nd:network-id&gt;
          &lt;nd:network-types&gt;
            &lt;bsc:bsc-topology xmlns:bsc="urn:TBD:params:xml:ns:yang:bsc:bsc-topology"/&gt;
          &lt;/nd:network-types&gt;
          &lt;nd:node&gt;
            &lt;nd:node-id&gt;407201001A&lt;/nd:node-id&gt;
            &lt;nt:termination-point xmlns:nt="urn:TBD:params:xml:ns:yang:links"&gt;
              &lt;nt:tp-id&gt;SERVICE_TP&lt;/nt:tp-id&gt;
            &lt;/nt:termination-point&gt;
          &lt;/nd:node&gt;
          &lt;nd:node&gt;
            &lt;nd:node-id&gt;407850001A&lt;/nd:node-id&gt;
            &lt;nt:termination-point xmlns:nt="urn:TBD:params:xml:ns:yang:links"&gt;
              &lt;nt:tp-id&gt;SERVICE_TP&lt;/nt:tp-id&gt;
            &lt;/nt:termination-point&gt;
          &lt;/nd:node&gt;
          &lt;nt:link xmlns:nt="urn:TBD:params:xml:ns:yang:links"&gt;
            &lt;nt:link-id&gt;407201001A-407850001A-Ater&lt;/nt:link-id&gt;
            &lt;nt:source&gt;
              &lt;nt:source-node&gt;407201001A&lt;/nt:source-node&gt;
              &lt;nt:source-tp&gt;SERVICE_TP&lt;/nt:source-tp&gt;
            &lt;/nt:source&gt;
            &lt;nt:destination&gt;
              &lt;nt:dest-node&gt;407850001A&lt;/nt:dest-node&gt;
              &lt;nt:dest-tp&gt;SERVICE_TP&lt;/nt:dest-tp&gt;
            &lt;/nt:destination&gt;
            &lt;bsc:bsc-link-attributes xmlns:bsc="urn:TBD:params:xml:ns:yang:bsc:bsc-topology"&gt;
              &lt;bsc:link-usage&gt;Ater&lt;/bsc:link-usage&gt;
            &lt;/bsc:bsc-link-attributes&gt;
          &lt;/nt:link&gt;
        &lt;/nd:network&gt;
      &lt;/config&gt;
  </code></pre>
  
  <p><strong>Pyang validation output</strong></p>
  
  <pre><code>yang2dsdl -j -s -b nodes_network-topology_bsc-topology -t config -v foo3.xml
  == Using pre-generated schemas
  
  == Validating grammar and datatypes ...
  foo3.xml validates.
  
  == Adding default values... done.
  
  == Validating semantic constraints ...
  --- Failed assert at "/nc:config/nd:network/lnk:link/bsc:bsc-link-attributes/bsc:link-usage":
      Condition "boolean(count(../../../nd:link) = 1)" must be true
  </code></pre>
  
  <p><strong>Question: Why would boolean(count(../../../nd:link) = 1) not evaluate to true ?</strong></p>
  
  <p>There is clearly one link in there. So what am I missing here ?</p>
  
  <p><strong>Other validations done</strong></p>
  
  <p>I did use the <a href="http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm" rel="nofollow">XPath Expression Testbed</a> to come up with a pointer what I am missing, but that tool gave me the expected result. Both in the case where I verified without a context node and the case where I set the context node to the <strong>link-usage</strong> node in the above XML file.</p>
  
  <p>Does anyone have any pointers to what I am missing ? </p>