tech-invite   World Map     

IETF     RFCs     Groups     SIP     ABNFs    |    3GPP     Specs     Gloss.     Arch.     IMS     UICC    |    Misc.    |    search     info

RFC 7950

 
 
 

The YANG 1.1 Data Modeling Language

Part 5 of 9, p. 84 to 108
Prev Section       Next Section

 


prevText      Top      ToC       Page 84 
7.8.  The "list" Statement

   The "list" statement is used to define an interior data node in the
   schema tree.  A list node may exist in multiple instances in the data
   tree.  Each such instance is known as a list entry.  The "list"
   statement takes one argument, which is an identifier, followed by a
   block of substatements that holds detailed list information.

   A list entry is uniquely identified by the values of the list's keys,
   if defined.

Top      Up      ToC       Page 85 
7.8.1.  The list's Substatements

                 +--------------+---------+-------------+
                 | substatement | section | cardinality |
                 +--------------+---------+-------------+
                 | action       | 7.15    | 0..n        |
                 | anydata      | 7.10    | 0..n        |
                 | anyxml       | 7.11    | 0..n        |
                 | choice       | 7.9     | 0..n        |
                 | config       | 7.21.1  | 0..1        |
                 | container    | 7.5     | 0..n        |
                 | description  | 7.21.3  | 0..1        |
                 | grouping     | 7.12    | 0..n        |
                 | if-feature   | 7.20.2  | 0..n        |
                 | key          | 7.8.2   | 0..1        |
                 | leaf         | 7.6     | 0..n        |
                 | leaf-list    | 7.7     | 0..n        |
                 | list         | 7.8     | 0..n        |
                 | max-elements | 7.7.6   | 0..1        |
                 | min-elements | 7.7.5   | 0..1        |
                 | must         | 7.5.3   | 0..n        |
                 | notification | 7.16    | 0..n        |
                 | ordered-by   | 7.7.7   | 0..1        |
                 | reference    | 7.21.4  | 0..1        |
                 | status       | 7.21.2  | 0..1        |
                 | typedef      | 7.3     | 0..n        |
                 | unique       | 7.8.3   | 0..n        |
                 | uses         | 7.13    | 0..n        |
                 | when         | 7.21.5  | 0..1        |
                 +--------------+---------+-------------+

7.8.2.  The list's "key" Statement

   The "key" statement, which MUST be present if the list represents
   configuration and MAY be present otherwise, takes as an argument a
   string that specifies a space-separated list of one or more leaf
   identifiers of this list.  A leaf identifier MUST NOT appear more
   than once in the key.  Each such leaf identifier MUST refer to a
   child leaf of the list.  The leafs can be defined directly in
   substatements to the list or in groupings used in the list.

   The combined values of all the leafs specified in the key are used to
   uniquely identify a list entry.  All key leafs MUST be given values
   when a list entry is created.  Thus, any default values in the key
   leafs or their types are ignored.  Any "mandatory" statements in the
   key leafs are ignored.

Top      Up      ToC       Page 86 
   A leaf that is part of the key can be of any built-in or
   derived type.

   All key leafs in a list MUST have the same value for their "config"
   as the list itself.

   The key string syntax is formally defined by the rule "key-arg" in
   Section 14.

7.8.3.  The list's "unique" Statement

   The "unique" statement is used to put constraints on valid list
   entries.  It takes as an argument a string that contains a space-
   separated list of schema node identifiers, which MUST be given in the
   descendant form (see the rule "descendant-schema-nodeid" in
   Section 14).  Each such schema node identifier MUST refer to a leaf.

   If one of the referenced leafs represents configuration data, then
   all of the referenced leafs MUST represent configuration data.

   The "unique" constraint specifies that the combined values of all the
   leaf instances specified in the argument string, including leafs with
   default values, MUST be unique within all list entry instances in
   which all referenced leafs exist or have default values.  The
   constraint is enforced according to the rules in Section 8.

   The unique string syntax is formally defined by the rule "unique-arg"
   in Section 14.

7.8.3.1.  Usage Example

   With the following list:

     list server {
       key "name";
       unique "ip port";
       leaf name {
         type string;
       }
       leaf ip {
         type inet:ip-address;
       }
       leaf port {
         type inet:port-number;
       }
     }

Top      Up      ToC       Page 87 
   the following configuration is not valid:

     <server>
       <name>smtp</name>
       <ip>192.0.2.1</ip>
       <port>25</port>
     </server>

     <server>
       <name>http</name>
       <ip>192.0.2.1</ip>
       <port>25</port>
     </server>

   The following configuration is valid, since the "http" and "ftp" list
   entries do not have a value for all referenced leafs and are thus not
   taken into account when the "unique" constraint is enforced:

     <server>
       <name>smtp</name>
       <ip>192.0.2.1</ip>
       <port>25</port>
     </server>

     <server>
       <name>http</name>
       <ip>192.0.2.1</ip>
     </server>

     <server>
       <name>ftp</name>
       <ip>192.0.2.1</ip>
     </server>

7.8.4.  The list's Child Node Statements

   Within a list, the "container", "leaf", "list", "leaf-list", "uses",
   "choice", "anydata", and "anyxml" statements can be used to define
   child nodes to the list.

Top      Up      ToC       Page 88 
7.8.5.  XML Encoding Rules

   A list is encoded as a series of XML elements, one for each entry in
   the list.  Each element's local name is the list's identifier, and
   its namespace is the module's XML namespace (see Section 7.1.3).
   There is no XML element surrounding the list as a whole.

   The list's key nodes are encoded as subelements to the list's
   identifier element, in the same order as they are defined within the
   "key" statement.

   The rest of the list's child nodes are encoded as subelements to the
   list element, after the keys.  If the list defines RPC or action
   input or output parameters, the subelements are encoded in the same
   order as they are defined within the "list" statement.  Otherwise,
   the subelements are encoded in any order.

   Any whitespace between the subelements to the list entry is
   insignificant, i.e., an implementation MAY insert whitespace
   characters between subelements.

   The XML elements representing list entries MUST appear in the order
   specified by the user if the list is "ordered-by user"; otherwise,
   the order is implementation dependent.  The XML elements representing
   list entries MAY be interleaved with elements for siblings of the
   list, unless the list defines RPC or action input or output
   parameters.

7.8.6.  NETCONF <edit-config> Operations

   List entries can be created, deleted, replaced, and modified through
   <edit-config> by using the "operation" attribute in the list's XML
   element.  In each case, the values of all keys are used to uniquely
   identify a list entry.  If all keys are not specified for a list
   entry, a "missing-element" error is returned.

   In an "ordered-by user" list, the attributes "insert" and "key" in
   the YANG XML namespace (Section 5.3.1) can be used to control where
   in the list the entry is inserted.  These can be used during "create"
   operations to insert a new list entry, or during "merge" or "replace"
   operations to insert a new list entry or move an existing one.

   The "insert" attribute can take the values "first", "last", "before",
   and "after".  If the value is "before" or "after", the "key"
   attribute MUST also be used, to specify an existing element in the
   list.  The value of the "key" attribute is the key predicates of the
   full instance identifier (see Section 9.13) for the list entry.

Top      Up      ToC       Page 89 
   If no "insert" attribute is present in the "create" operation, it
   defaults to "last".

   If several entries in an "ordered-by user" list are modified in the
   same <edit-config> request, the entries are modified one at a time,
   in the order of the XML elements in the request.

   In a <copy-config> or in an <edit-config> with a "replace" operation
   that covers the entire list, the list entry order is the same as the
   order of the XML elements in the request.

   When a NETCONF server processes an <edit-config> request, the
   elements of procedure for a list node are as follows:

   o  If the operation is "merge" or "replace", the list entry is
      created if it does not exist.  If the list entry already exists
      and the "insert" and "key" attributes are present, the list entry
      is moved according to the values of the "insert" and "key"
      attributes.  If the list entry exists and the "insert" and "key"
      attributes are not present, the list entry is not moved.

   o  If the operation is "create", the list entry is created if it does
      not exist.  If the list entry already exists, a "data-exists"
      error is returned.

   o  If the operation is "delete", the entry is deleted from the list
      if it exists.  If the list entry does not exist, a "data-missing"
      error is returned.

Top      Up      ToC       Page 90 
7.8.7.  Usage Example

   Given the following list:

     list user {
       key "name";
       config true;
       description
         "This is a list of users in the system.";

       leaf name {
         type string;
       }
       leaf type {
         type string;
       }
       leaf full-name {
         type string;
       }
     }

   A corresponding XML instance example:

     <user>
       <name>fred</name>
       <type>admin</type>
       <full-name>Fred Flintstone</full-name>
     </user>

Top      Up      ToC       Page 91 
   To create a new user "barney":

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
       <edit-config>
         <target>
           <running/>
         </target>
         <config>
           <system xmlns="urn:example:config">
             <user nc:operation="create">
               <name>barney</name>
               <type>admin</type>
               <full-name>Barney Rubble</full-name>
             </user>
           </system>
         </config>
       </edit-config>
     </rpc>

   To change the type of "fred" to "superuser":

     <rpc message-id="102"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
       <edit-config>
         <target>
           <running/>
         </target>
         <config>
           <system xmlns="urn:example:config">
             <user>
               <name>fred</name>
               <type>superuser</type>
             </user>
           </system>
         </config>
       </edit-config>
     </rpc>

Top      Up      ToC       Page 92 
   Given the following ordered-by user list:

     list user {
       description
         "This is a list of users in the system.";
       ordered-by user;
       config true;

       key "first-name surname";

       leaf first-name {
         type string;
       }
       leaf surname {
         type string;
       }
       leaf type {
         type string;
       }
     }

   The following would be used to insert a new user "barney rubble"
   after the user "fred flintstone":

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:yang="urn:ietf:params:xml:ns:yang:1">
       <edit-config>
         <target>
           <running/>
         </target>
         <config>
           <system xmlns="urn:example:config"
                xmlns:ex="urn:example:config">
             <user nc:operation="create"
                   yang:insert="after"
                   yang:key="[ex:first-name='fred']
                             [ex:surname='flintstone']">
               <first-name>barney</first-name>
               <surname>rubble</surname>
               <type>admin</type>
             </user>
           </system>
         </config>
       </edit-config>
     </rpc>

Top      Up      ToC       Page 93 
   The following would be used to move the user "barney rubble" before
   the user "fred flintstone":

     <rpc message-id="102"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:yang="urn:ietf:params:xml:ns:yang:1">
       <edit-config>
         <target>
           <running/>
         </target>
         <config>
           <system xmlns="urn:example:config"
                xmlns:ex="urn:example:config">
             <user nc:operation="merge"
                   yang:insert="before"
                   yang:key="[ex:name='fred']
                             [ex:surname='flintstone']">
               <first-name>barney</first-name>
               <surname>rubble</surname>
             </user>
           </system>
         </config>
       </edit-config>
     </rpc>

7.9.  The "choice" Statement

   The "choice" statement defines a set of alternatives, only one of
   which may be present in any one data tree.  The argument is an
   identifier, followed by a block of substatements that holds detailed
   choice information.  The identifier is used to identify the choice
   node in the schema tree.  A choice node does not exist in the data
   tree.

   A choice consists of a number of branches, each defined with a "case"
   substatement.  Each branch contains a number of child nodes.  The
   nodes from at most one of the choice's branches exist at the same
   time.

   Since only one of the choice's cases can be valid at any time in the
   data tree, the creation of a node from one case implicitly deletes
   all nodes from all other cases.  If a request creates a node from a
   case, the server will delete any existing nodes that are defined in
   other cases inside the choice.

Top      Up      ToC       Page 94 
7.9.1.  The choice's Substatements

                 +--------------+---------+-------------+
                 | substatement | section | cardinality |
                 +--------------+---------+-------------+
                 | anydata      | 7.10    | 0..n        |
                 | anyxml       | 7.11    | 0..n        |
                 | case         | 7.9.2   | 0..n        |
                 | choice       | 7.9     | 0..n        |
                 | config       | 7.21.1  | 0..1        |
                 | container    | 7.5     | 0..n        |
                 | default      | 7.9.3   | 0..1        |
                 | description  | 7.21.3  | 0..1        |
                 | if-feature   | 7.20.2  | 0..n        |
                 | leaf         | 7.6     | 0..n        |
                 | leaf-list    | 7.7     | 0..n        |
                 | list         | 7.8     | 0..n        |
                 | mandatory    | 7.9.4   | 0..1        |
                 | reference    | 7.21.4  | 0..1        |
                 | status       | 7.21.2  | 0..1        |
                 | when         | 7.21.5  | 0..1        |
                 +--------------+---------+-------------+

7.9.2.  The choice's "case" Statement

   The "case" statement is used to define branches of the choice.  It
   takes as an argument an identifier, followed by a block of
   substatements that holds detailed case information.

   The identifier is used to identify the case node in the schema tree.
   A case node does not exist in the data tree.

   Within a "case" statement, the "anydata", "anyxml", "choice",
   "container", "leaf", "list", "leaf-list", and "uses" statements can
   be used to define child nodes to the case node.  The identifiers of
   all these child nodes MUST be unique within all cases in a choice.
   For example, the following is illegal:

     choice interface-type {     // This example is illegal YANG
       case a {
         leaf ethernet { ... }
       }
       case b {
         container ethernet { ...}
       }
     }

Top      Up      ToC       Page 95 
   As a shorthand, the "case" statement can be omitted if the branch
   contains a single "anydata", "anyxml", "choice", "container", "leaf",
   "list", or "leaf-list" statement.  In this case, the case node still
   exists in the schema tree, and its identifier is the same as the
   identifier of the child node.  Schema node identifiers (Section 6.5)
   MUST always explicitly include case node identifiers.  The following
   example:

     choice interface-type {
       container ethernet { ... }
     }

   is equivalent to:

     choice interface-type {
       case ethernet {
         container ethernet { ... }
       }
     }

   The case identifier MUST be unique within a choice.

7.9.2.1.  The case's Substatements

                 +--------------+---------+-------------+
                 | substatement | section | cardinality |
                 +--------------+---------+-------------+
                 | anydata      | 7.10    | 0..n        |
                 | anyxml       | 7.11    | 0..n        |
                 | choice       | 7.9     | 0..n        |
                 | container    | 7.5     | 0..n        |
                 | description  | 7.21.3  | 0..1        |
                 | if-feature   | 7.20.2  | 0..n        |
                 | leaf         | 7.6     | 0..n        |
                 | leaf-list    | 7.7     | 0..n        |
                 | list         | 7.8     | 0..n        |
                 | reference    | 7.21.4  | 0..1        |
                 | status       | 7.21.2  | 0..1        |
                 | uses         | 7.13    | 0..n        |
                 | when         | 7.21.5  | 0..1        |
                 +--------------+---------+-------------+

Top      Up      ToC       Page 96 
7.9.3.  The choice's "default" Statement

   The "default" statement indicates if a case should be considered as
   the default if no child nodes from any of the choice's cases exist.
   The argument is the identifier of the default "case" statement.  If
   the "default" statement is missing, there is no default case.

   The "default" statement MUST NOT be present on choices where
   "mandatory" is "true".

   The default case is only important when considering the "default"
   statements of nodes under the cases (i.e., default values of leafs
   and leaf-lists, and default cases of nested choices).  The default
   values and nested default cases under the default case are used if
   none of the nodes under any of the cases are present.

   There MUST NOT be any mandatory nodes (Section 3) directly under the
   default case.

   Default values for child nodes under a case are only used if one of
   the nodes under that case is present or if that case is the default
   case.  If none of the nodes under a case are present and the case is
   not the default case, the default values of the cases' child nodes
   are ignored.

Top      Up      ToC       Page 97 
   In this example, the choice defaults to "interval", and the default
   value will be used if none of "daily", "time-of-day", or "manual" are
   present.  If "daily" is present, the default value for "time-of-day"
   will be used.

     container transfer {
       choice how {
         default interval;
         case interval {
           leaf interval {
             type uint16;
             units minutes;
             default 30;
           }
         }
         case daily {
           leaf daily {
             type empty;
           }
           leaf time-of-day {
             type string;
             units 24-hour-clock;
             default "01.00";
           }
         }
         case manual {
           leaf manual {
             type empty;
           }
         }
       }
     }

Top      Up      ToC       Page 98 
7.9.4.  The choice's "mandatory" Statement

   The "mandatory" statement, which is optional, takes as an argument
   the string "true" or "false" and puts a constraint on valid data.  If
   "mandatory" is "true", at least one node from exactly one of the
   choice's case branches MUST exist.

   If not specified, the default is "false".

   The behavior of the constraint depends on the type of the choice's
   closest ancestor node in the schema tree that is not a non-presence
   container (see Section 7.5.1):

   o  If no such ancestor exists in the schema tree, the constraint is
      enforced.

   o  Otherwise, if this ancestor is a case node, the constraint is
      enforced if any other node from the case exists.

   o  Otherwise, it is enforced if the ancestor node exists.

   The constraint is further enforced according to the rules in
   Section 8.

7.9.5.  XML Encoding Rules

   The choice and case nodes are not visible in XML.

   The child nodes of the selected "case" statement MUST be encoded in
   the same order as they are defined in the "case" statement if they
   are part of an RPC or action input or output parameter definition.
   Otherwise, the subelements are encoded in any order.

Top      Up      ToC       Page 99 
7.9.6.  Usage Example

   Given the following choice:

     container protocol {
       choice name {
         case a {
           leaf udp {
             type empty;
           }
         }
         case b {
           leaf tcp {
             type empty;
           }
         }
       }
     }

   A corresponding XML instance example:

     <protocol>
       <tcp/>
     </protocol>

   To change the protocol from TCP to UDP:

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
       <edit-config>
         <target>
           <running/>
         </target>
         <config>
           <system xmlns="urn:example:config">
             <protocol>
               <udp nc:operation="create"/>
             </protocol>
           </system>
         </config>
       </edit-config>
     </rpc>

Top      Up      ToC       Page 100 
7.10.  The "anydata" Statement

   The "anydata" statement defines an interior node in the schema tree.
   It takes one argument, which is an identifier, followed by a block of
   substatements that holds detailed anydata information.

   The "anydata" statement is used to represent an unknown set of nodes
   that can be modeled with YANG, except anyxml, but for which the data
   model is not known at module design time.  It is possible, though not
   required, for the data model for anydata content to become known
   through protocol signaling or other means that are outside the scope
   of this document.

   An example of where anydata can be useful is a list of received
   notifications where the specific notifications are not known at
   design time.

   An anydata node cannot be augmented (see Section 7.17).

   An anydata node exists in zero or one instance in the data tree.

   An implementation may or may not know the data model used to model a
   specific instance of an anydata node.

   Since the use of anydata limits the manipulation of the content, the
   "anydata" statement SHOULD NOT be used to define configuration data.

7.10.1.  The anydata's Substatements

                 +--------------+---------+-------------+
                 | substatement | section | cardinality |
                 +--------------+---------+-------------+
                 | config       | 7.21.1  | 0..1        |
                 | description  | 7.21.3  | 0..1        |
                 | if-feature   | 7.20.2  | 0..n        |
                 | mandatory    | 7.6.5   | 0..1        |
                 | must         | 7.5.3   | 0..n        |
                 | reference    | 7.21.4  | 0..1        |
                 | status       | 7.21.2  | 0..1        |
                 | when         | 7.21.5  | 0..1        |
                 +--------------+---------+-------------+

Top      Up      ToC       Page 101 
7.10.2.  XML Encoding Rules

   An anydata node is encoded as an XML element.  The element's local
   name is the anydata's identifier, and its namespace is the module's
   XML namespace (see Section 7.1.3).  The value of the anydata node is
   a set of nodes, which are encoded as XML subelements to the anydata
   element.

7.10.3.  NETCONF <edit-config> Operations

   An anydata node is treated as an opaque chunk of data.  This data can
   be modified in its entirety only.

   Any "operation" attributes present on subelements of an anydata node
   are ignored by the NETCONF server.

   When a NETCONF server processes an <edit-config> request, the
   elements of procedure for the anydata node are as follows:

   o  If the operation is "merge" or "replace", the node is created if
      it does not exist, and its value is set to the subelements of the
      anydata node found in the XML RPC data.

   o  If the operation is "create", the node is created if it does not
      exist, and its value is set to the subelements of the anydata node
      found in the XML RPC data.  If the node already exists, a
      "data-exists" error is returned.

   o  If the operation is "delete", the node is deleted if it exists.
      If the node does not exist, a "data-missing" error is returned.

7.10.4.  Usage Example

   Given the following "anydata" statement:

     list logged-notification {
       key time;
       leaf time {
         type yang:date-and-time;
       }
       anydata data;
     }

Top      Up      ToC       Page 102 
   The following is a valid encoding of such a list instance:

     <logged-notification>
       <time>2014-07-29T13:43:12Z</time>
       <data>
         <notification
           xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
           <eventTime>2014-07-29T13:43:01Z</eventTime>
           <event xmlns="urn:example:event">
             <event-class>fault</event-class>
             <reporting-entity>
               <card>Ethernet0</card>
             </reporting-entity>
             <severity>major</severity>
           </event>
         </notification>
       </data>
     </logged-notification>

7.11.  The "anyxml" Statement

   The "anyxml" statement defines an interior node in the schema tree.
   It takes one argument, which is an identifier, followed by a block of
   substatements that holds detailed anyxml information.

   The "anyxml" statement is used to represent an unknown chunk of XML.
   No restrictions are placed on the XML.  This can be useful, for
   example, in RPC replies.  An example is the <filter> parameter in the
   <get-config> operation in NETCONF.

   An anyxml node cannot be augmented (see Section 7.17).

   An anyxml node exists in zero or one instance in the data tree.

   Since the use of anyxml limits the manipulation of the content, the
   "anyxml" statement SHOULD NOT be used to define configuration data.

   It should be noted that in YANG version 1, "anyxml" was the only
   statement that could model an unknown hierarchy of data.  In many
   cases, this unknown hierarchy of data is actually modeled in YANG,
   but the specific YANG data model is not known at design time.  In
   these situations, it is RECOMMENDED to use "anydata" (Section 7.10)
   instead of "anyxml".

Top      Up      ToC       Page 103 
7.11.1.  The anyxml's Substatements

                 +--------------+---------+-------------+
                 | substatement | section | cardinality |
                 +--------------+---------+-------------+
                 | config       | 7.21.1  | 0..1        |
                 | description  | 7.21.3  | 0..1        |
                 | if-feature   | 7.20.2  | 0..n        |
                 | mandatory    | 7.6.5   | 0..1        |
                 | must         | 7.5.3   | 0..n        |
                 | reference    | 7.21.4  | 0..1        |
                 | status       | 7.21.2  | 0..1        |
                 | when         | 7.21.5  | 0..1        |
                 +--------------+---------+-------------+

7.11.2.  XML Encoding Rules

   An anyxml node is encoded as an XML element.  The element's local
   name is the anyxml's identifier, and its namespace is the module's
   XML namespace (see Section 7.1.3).  The value of the anyxml node is
   encoded as XML content of this element.

   Note that any XML prefixes used in the encoding are local to each
   instance encoding.  This means that the same XML may be encoded
   differently by different implementations.

7.11.3.  NETCONF <edit-config> Operations

   An anyxml node is treated as an opaque chunk of data.  This data can
   be modified in its entirety only.

   Any "operation" attributes present on subelements of an anyxml node
   are ignored by the NETCONF server.

   When a NETCONF server processes an <edit-config> request, the
   elements of procedure for the anyxml node are as follows:

   o  If the operation is "merge" or "replace", the node is created if
      it does not exist, and its value is set to the XML content of the
      anyxml node found in the XML RPC data.

   o  If the operation is "create", the node is created if it does not
      exist, and its value is set to the XML content of the anyxml node
      found in the XML RPC data.  If the node already exists, a
      "data-exists" error is returned.

   o  If the operation is "delete", the node is deleted if it exists.
      If the node does not exist, a "data-missing" error is returned.

Top      Up      ToC       Page 104 
7.11.4.  Usage Example

   Given the following "anyxml" statement:

     anyxml html-info;

   The following are two valid encodings of the same anyxml value:

      <html-info>
        <p xmlns="http://www.w3.org/1999/xhtml">
          This is <em>very</em> cool.
        </p>
      </html-info>

      <html-info>
        <x:p xmlns:x="http://www.w3.org/1999/xhtml">
          This is <x:em>very</x:em> cool.
        </x:p>
      </html-info>

7.12.  The "grouping" Statement

   The "grouping" statement is used to define a reusable block of nodes,
   which may be used locally in the module or submodule, and by other
   modules that import from it, according to the rules in Section 5.5.
   It takes one argument, which is an identifier, followed by a block of
   substatements that holds detailed grouping information.

   The "grouping" statement is not a data definition statement and, as
   such, does not define any nodes in the schema tree.

   A grouping is like a "structure" or a "record" in conventional
   programming languages.

   Once a grouping is defined, it can be referenced in a "uses"
   statement (see Section 7.13).  A grouping MUST NOT reference itself,
   neither directly nor indirectly through a chain of other groupings.

   If the grouping is defined at the top level of a YANG module or
   submodule, the grouping's identifier MUST be unique within the
   module.

   A grouping is more than just a mechanism for textual substitution;
   it also defines a collection of nodes.  Identifiers appearing inside
   the grouping are resolved relative to the scope in which the grouping
   is defined, not where it is used.  Prefix mappings, type names,
   grouping names, and extension usage are evaluated in the hierarchy

Top      Up      ToC       Page 105 
   where the "grouping" statement appears.  For extensions, this means
   that extensions defined as direct children to a "grouping" statement
   are applied to the grouping itself.

   Note that if a grouping defines an action or a notification node in
   its hierarchy, then it cannot be used in all contexts.  For example,
   it cannot be used in an rpc definition.  See Sections 7.15 and 7.16.

7.12.1.  The grouping's Substatements

                 +--------------+---------+-------------+
                 | substatement | section | cardinality |
                 +--------------+---------+-------------+
                 | action       | 7.15    | 0..n        |
                 | anydata      | 7.10    | 0..n        |
                 | anyxml       | 7.11    | 0..n        |
                 | choice       | 7.9     | 0..n        |
                 | container    | 7.5     | 0..n        |
                 | description  | 7.21.3  | 0..1        |
                 | grouping     | 7.12    | 0..n        |
                 | leaf         | 7.6     | 0..n        |
                 | leaf-list    | 7.7     | 0..n        |
                 | list         | 7.8     | 0..n        |
                 | notification | 7.16    | 0..n        |
                 | reference    | 7.21.4  | 0..1        |
                 | status       | 7.21.2  | 0..1        |
                 | typedef      | 7.3     | 0..n        |
                 | uses         | 7.13    | 0..n        |
                 +--------------+---------+-------------+

7.12.2.  Usage Example

     import ietf-inet-types {
       prefix "inet";
     }

     grouping endpoint {
       description "A reusable endpoint group.";
       leaf ip {
         type inet:ip-address;
       }
       leaf port {
         type inet:port-number;
       }
     }

Top      Up      ToC       Page 106 
7.13.  The "uses" Statement

   The "uses" statement is used to reference a "grouping" definition.
   It takes one argument, which is the name of the grouping.

   The effect of a "uses" reference to a grouping is that the nodes
   defined by the grouping are copied into the current schema tree and
   are then updated according to the "refine" and "augment" statements.

   The identifiers defined in the grouping are not bound to a namespace
   until the contents of the grouping are added to the schema tree via a
   "uses" statement that does not appear inside a "grouping" statement,
   at which point they are bound to the namespace of the current module.

7.13.1.  The uses's Substatements

                 +--------------+---------+-------------+
                 | substatement | section | cardinality |
                 +--------------+---------+-------------+
                 | augment      | 7.17    | 0..n        |
                 | description  | 7.21.3  | 0..1        |
                 | if-feature   | 7.20.2  | 0..n        |
                 | reference    | 7.21.4  | 0..1        |
                 | refine       | 7.13.2  | 0..n        |
                 | status       | 7.21.2  | 0..1        |
                 | when         | 7.21.5  | 0..1        |
                 +--------------+---------+-------------+

7.13.2.  The "refine" Statement

   Some of the properties of each node in the grouping can be refined
   with the "refine" statement.  The argument is a string that
   identifies a node in the grouping.  This node is called the refine's
   target node.  If a node in the grouping is not present as a target
   node of a "refine" statement, it is not refined and thus is used
   exactly as it was defined in the grouping.

   The argument string is a descendant schema node identifier (see
   Section 6.5).

   The following refinements can be done:

   o  A leaf or choice node may get a default value, or a new default
      value if it already had one.

   o  A leaf-list node may get a set of default values, or a new set of
      default values if it already had defaults; i.e., the set of
      refined default values replaces the defaults already given.

Top      Up      ToC       Page 107 
   o  Any node may get a specialized "description" string.

   o  Any node may get a specialized "reference" string.

   o  Any node may get a different "config" statement.

   o  A leaf, anydata, anyxml, or choice node may get a different
      "mandatory" statement.

   o  A container node may get a "presence" statement.

   o  A leaf, leaf-list, list, container, anydata, or anyxml node may
      get additional "must" expressions.

   o  A leaf-list or list node may get a different "min-elements" or
      "max-elements" statement.

   o  A leaf, leaf-list, list, container, choice, case, anydata, or
      anyxml node may get additional "if-feature" expressions.

   o  Any node can get refined extensions, if the extension allows
      refinement.  See Section 7.19 for details.

7.13.3.  XML Encoding Rules

   Each node in the grouping is encoded as if it was defined inline,
   even if it is imported from another module with another XML
   namespace.

7.13.4.  Usage Example

   To use the "endpoint" grouping defined in Section 7.12.2 in a
   definition of an HTTP server in some other module, we can do:

     import example-system {
       prefix "sys";
     }

     container http-server {
       leaf name {
         type string;
       }
       uses sys:endpoint;
     }

Top      Up      ToC       Page 108 
   A corresponding XML instance example:

     <http-server>
       <name>extern-web</name>
       <ip>192.0.2.1</ip>
       <port>80</port>
     </http-server>

   If port 80 should be the default for the HTTP server, a default can
   be added:

     container http-server {
       leaf name {
         type string;
       }
       uses sys:endpoint {
         refine port {
           default 80;
         }
       }
     }

   If we want to define a list of servers and each server has "ip" and
   "port" as keys, we can do:

     list server {
       key "ip port";
       leaf name {
         type string;
       }
       uses sys:endpoint;
     }

   The following is an error:

     container http-server {
       uses sys:endpoint;
       leaf ip {          // illegal - same identifier "ip" used twice
         type string;
       }
     }



(page 108 continued on part 6)

Next Section