The union built-in type represents a value that corresponds to one of its member types. Type statement is repeatedly used to specify each member type of the union. A union cannot be restricted.  However, each member type can be restricted.

Consider the following YANG module example:


module example {
  namespace "http://yumaworks.com/ns/example";
  prefix "example";

  revision 2019-07-30 {
    description
      "Initial example module for union type";
  }  
  
  leaf yang-union-example {
    type union {
      type int8;
      type decimal64 { fraction-digits 3; }
    }
  }
}


This leaf can be accessed using several ways described below.


1) Using RESTCONF request:


To create a new "yang-union-example" node using RESTCONF client, the client might send the following POST request:


      POST /restconf/data/path/to/node  HTTP/1.1
      Host: example-server
      Content-Type: application/yang-data+json

      {
        "yang-union-example":"15"
      }


If the resource is created, the server might respond as follows:


      HTTP/1.1 201 Created
      Server: example-server
      Location: https://example-server/restconf/data/yang-union-example


If the POST method succeeds, a "201 Created" Status is returned and there is no response message-body.  A "Location" header field identifying the resource node that was created. If the data resource already exists, then the POST request will fail and a "409 Conflict" status-line will be returned.


To retrieve just created node, the GET method can be sent by the client as follows:


      GET /restconf/data/path/to/node/yang-union-type HTTP/1.1
      Host: example-server
      Accept: application/yang-data+xml


The server might respond as follows:


      HTTP/1.1 200 OK
      Server: example-server
      Content-Type: application/yang-data+xml

      <yang-union-example xmlns="http://yumaworks.com/ns/example">15</yang-union-example>



2) Using yangcli-pro:


To create a new "yang-union-example" node using yangcli-pro client, the client might send the following POST request:


user@server> create /path/to/yang-union-example value=15
user@server> commit


To retrieve just created union leaf, the following request might be sent:


user@server> sget /yang-union-example


The server might respond with rpc-reply, containing below information:


<rpc-reply>
 <data>
   <yang-union-example xmlns="http://yumaworks.com/ns/example">15</yang-union-example>
 </data>
</rpc-reply>


The following example illustrates how the union leaf can be set by using inline JSON file:


edit-config target=candidate config="""
{"config": {
    "yang-union-example" : "15"
 }
}
"""


The following example illustrates how the union leaf can be set by using inline XML file:


edit-config target=candidate config="""
<config>
  <yang-union-example>15</yang-union-example>
</config>
"""


To retrieve just created union leaf, the following request might be sent:


user@server> sget /yang-union-example


The server might respond with rpc-reply, containing below information:


<rpc-reply>
 <data>
   <yang-union-example xmlns="http://yumaworks.com/ns/example">15</yang-union-example>
 </data>
</rpc-reply>


Yangcli-pro will output this message as follows.


rpc-reply {
  data {
      yang-union-example 15
  }
}

3) Using DB-API:


The following example illustrates how to set union leaf value using DB-API.


/********************************************************************
* FUNCTION send_test_edit
*
* This is an example send edit function for union node.
**********************************************************************/
static void
    send_test_edit (void)
{
    const xmlChar *path_str = (const xmlChar *)"/";
    const xmlChar *operation_str = (const xmlChar *)"merge";
    const xmlChar *value_str = (const xmlChar *)
    "<config>"
    "<yang-union-example xmlns='http://yumaworks.com/ns/example'>15</yang-union-example>"
    "</config>";

    const xmlChar *patch_id_str = NULL;
    boolean system_edit = FALSE;
    status_t res = db_api_send_edit_ex(path_str,
                                       operation_str,
                                       value_str,
                                       patch_id_str,
                                       system_edit);
    if (res != NO_ERR) {
        log_error("\nSend test edit for union node failed %s %s = %s (%s)\n",
                  operation_str, path_str, value_str,
                  get_error_string(res));
    } else if (LOGDEBUG) {
        log_debug("\nSend test edit for union node OK  %s %s = %s\n",
                  operation_str, path_str, value_str);
    }

} /* send_test_edit */

UNION leaf and SIL code:


The following API can be used with the union type val value node. Refer to val.h:

  • val_make_simval_obj()Function that malloc a new val value node and does not need to know the type, it will be picked automatically based on the provided object type.


Following code example creates the value of union node and outputs it to the standard log output using val_make_simval_obj().

This is just an example of how the following API can be used:


...
    /* create a new union type leaf, set it to be decimal.
     * Use decimal value to set it to decimal type.
     * Use int8 type value to set it to int8 type
     */
    val_value_t *return_val =
        val_make_simval_obj(obj, (const xmlChar *)"1.2", &res);
    if (return_val) {

        /* Just get the value of the node in string format */
        xmlChar *valstr = val_make_sprintf_string(return_val);
        if (valstr == NULL) {
            return;
        }

        log_info("\nCreated '%s' node; type:%s; value:%s",
                 VAL_NAME(return_val),
                 VAL_TYPDEF(return_val)->typenamestr,
                 valstr);

        m__free(valstr);
    }
...


The server might output the following logging information to the standard output:


...
Created 'yang-union-example' node; type:decimal64; value:1.2
...