YANG Objects

This section describes the basic design of the YANG object tree and the API functions to access this tree.

Object Trees

The object tree is a tree representation of all the YANG module rpc, data definition, and notification statements. It starts with a 'root' container. This is defined with a YANG container statement which has an ncx:root extension statement within it. The <config> parameter within the <edit-config> operation is an example of an object node which is treated as a root container. Each configuration database maintained by the server (E.g., <candidate> and <running>) has a root container value node as its top-level object.

A root container does not have any child nodes defined in it within the YANG file. However, the YumaPro tools will treat this special container as if any top-level YANG data node is allowed to be a child node of the 'root' container type.

Object Tree Ordering

Top-Level Data Nodes are derived from:

  • data-def-stmt

  • rpc-stmt

  • notification-stmt

The YANG object tree is maintained in “schema order” wherever that is defined.

  • Top-Level Data Nodes:

    • These nodes are sorted:

      • Primary Key: local-name

      • Secondary Key: module-name

    • The top-level YANG objects from all loaded modules are present in the object tree (except if removed by status=obsolete or deviation=not-supported)

  • Child Data Nodes, RPC and Notification Nodes

    • Child nodes defined in the current module are in schema order (order they appear in the YANG module

    • Augmenting child nodes are in no defined order. They will be after all the real child nodes and the order may change depending on how the augmenting modules are loaded.

      • DO NOT DEPEND ON THE ORDER OF AUGMENTING DATA NODES

Object Node Types

There are 14 different YANG object node types, and a discriminated union of sub-data structures contains fields common to each sub-type. Object templates are defined in ncx/obj.h.

YANG Object Types

enum obj_type_t

enumeration for different YANG data def statement types the enum order is significant!!! do not change!!!

Values:

enumerator OBJ_TYP_NONE

not set

enumerator OBJ_TYP_ANYXML

This object represents a YANG 1.1 anydata data node.

enumerator OBJ_TYP_CONTAINER

This object represents a YANG presence or non-presence container.

  • If the ncx:root stmt present then the object represents a NETCONF database root, and no direct child nodes are expected

enumerator OBJ_TYP_LEAF

This object represents a YANG leaf data node.

enumerator OBJ_TYP_LEAF_LIST

This object represents a YANG leaf-list data node.

enumerator OBJ_TYP_LIST

This object represents a YANG list data node.

enumerator OBJ_TYP_CHOICE

This object represents a YANG choice schema node.

  • The only children allowed are case objects.

  • This object does not have instances in the data tree.

enumerator OBJ_TYP_CASE

This object represents a YANG case schema node.

  • This object does not have instances in the data tree. case: last named database object

enumerator OBJ_TYP_USES

This object represents a YANG uses schema node.

  • The contents of the grouping it represents will be expanded into object tree.

  • It is saved in the object tree even during operation, in order for the expanded objects to share common data.

  • This object does not have instances in the data tree.

  • Object has no name: The obj_get_name function returns the string 'uses'

enumerator OBJ_TYP_REFINE

This object represents a YANG refine statement.

  • It is used to alter the grouping contents during the expansion of a uses statement.

  • Must be a direct child of 'uses' stmt

  • It does not have instances in the data tree.

enumerator OBJ_TYP_AUGMENT

This object represents a YANG augment statement.

  • It is used to add additional child objects to an existing data definition statement.

  • This object is only allowed to be a child of a uses

  • statement or a top-level stateement within the module

  • It does not have instances in the data tree, however any children of the augment node will generate object nodes that have instances in the data tree.

enumerator OBJ_TYP_RPC

This object represents a YANG rpc statement.

  • It is used to define new <rpc> operations.

  • This object will only appear as a top-level statement within the module.

  • It does not have instances in the data tree.

  • Only 'rpcio' nodes are allowed to be children of an RPC node.

enumerator OBJ_TYP_RPCIO

This object represents a YANG input or output statement.

  • It is used to define input or output for an <rpc> operation.

  • This object will only appear as a child of an RPC node.

  • It does not have instances in the data tree. rpc input or output

enumerator OBJ_TYP_NOTIF

This object represents a YANG notification statement.

  • It is used to define new <notification> event types.

  • This object will only appear as a top-level statement within the module.

  • It does not have instances in the data tree.

enumerator OBJ_TYP_ANYDATA

This object represents a YANG 1.1 anydata data node.

enumerator OBJ_TYP_ACTION

This object represents a YANG 1.1 action schema node.

  • It is used to define a data-node specific operation.

  • The parent node must be a container or list

  • NMDA specifies all actions are accessed in <operational> not really data, YANG 1.1 only

obj_template_t

The following typedef is used to represent an object tree node:

struct obj_template_t

One YANG data-def-stmt.

Public Members

dlq_hdr_t qhdr

queue header

obj_type_t objtype

object type (def)

uint32 yang_hash

experimental: not used

uint32 flags

see OBJ_FL_* definitions

uint32 xflags

see OBJ_FL_* definitions

uint32 xflags2

see OBJ_FL_* definitions

uint32 uflags

see OBJ_FL_* definitions

uint8 silflags

see OBJ_FL_* definitions

uint8 sil_priority

picks SIL callback order

obj_testflags_t testflags

see AGT_TEST_FL_* definitions

obj_testflags_t desc_testflags

see AGT_TEST_FL_* definitions

ncx_error_t tkerr

file and line info for compiler

grp_template_t *grp

non-NULL == in a grp.datadefQ

obj_index_t index

object index for val_child ordering

obj_oid_t *oid

SNMP OID for this object (set if needed)

boolean set_snmp_flags

need SNMP flags

boolean xpath_oper_ok

object OK for referencing oper-data in XPath

struct obj_template_t_ *parent

backptr to parent

struct obj_template_t_ *usesobj

backptr to uses-obj if grouping expand

struct obj_template_t_ *augobj

backptr to augment-obj if augment expand

struct xpath_pcb_t_ *when

optional when clause

dlq_hdr_t metadataQ

Q of obj_metadata_t.

dlq_hdr_t appinfoQ

Q of ncx_appinfo_t.

dlq_hdr_t iffeatureQ

Q of ncx_iffeature_t.

dlq_hdr_t inherited_iffeatureQ

Q of obj_iffeature_ptr_t.

dlq_hdr_t inherited_whenQ

Q of ncx_backptr_t with node == xpath_pcb_t.

dlq_hdr_t *dataruleQ

Q obj NACM data-rule backptrs.

void *cbset

cbset is different based on the object type:

void *get2cb

get2fn is getcb_fn2_t for local GET2

struct ncx_module_t_ *mod

object module and namespace ID assigned at runtime this can be changed over and over as a uses statement is expanded.

The final expansion into a real object will leave the correct value in place

xmlns_id_t nsid

namespace ID assigned to the object at run-time

struct xpath_pcb_t_ *xpath_backptr[OBJ_NUM_XPATH_BACKPTRS]

xpath backptr caching support

dlq_hdr_t xpath_backptrQ

Q of ncx_back_ptr_t with node == xpath_pcb_t.

void *commit_test_cb

backptr to the commit_test record for this object which will only exist if this object has 'must' or 'when' statements defined within it

dlq_hdr_t *errmsgQ

custom error message used if this is the server running

void *yangmap_cb

if set, backptr to the nodemap in a YANG model mapping OBJ_IS_YANGMAP_SOURCE() indicates this is the source node OBJ_IS_YANGMAP_TARGET() indicates this is the target node

ncx_transaction_id_t edit_txid

current edit transaction ID for commit test pruning

ncx_transaction_id_t must_txid

current edit transaction ID for MUST test default nodes pruning

ncx_transaction_id_t when_txid

current edit transaction ID for WHEN test default nodes pruning

ncx_transaction_id_t leafref_txid

current edit transaction ID for intermediate leafref processing

union obj_template_t::def_ def
void *def_hook_cb

def_hook_cb is ncx_def_hook_cbfn_t callback function for Dynamic Default Hook callback.

void *bool_eval_cb

The bool_eval_cb callback function may be set to allow XPath eval to be done by the callback instead of the real XPath parser.

See xpath.h typedef for details for xpath_bool_eval_fn_t function

ncx_sm_rootcb_t *rootcb

Schema Mount Control Block.

ncx_sid_t yang_sid

Each object specific variant has a YANG SID assigned for CBOR encoding.

The augment and uses variants do not actually get SID assignments.

uint32 yang_sid_tree

SID tree assignment if yang_sid is used.

union def_

object specific variants

Public Members

obj_container_t *container
obj_leaf_t *leaf
obj_leaflist_t *leaflist
obj_list_t *list
obj_choice_t *choic
obj_case_t *cas
obj_uses_t *uses
obj_refine_t *refine
obj_augment_t *augment
obj_rpc_t *rpc
obj_rpcio_t *rpcio
obj_notif_t *notif

obj_template_t Access Functions

The file ncx/obj.h contains many API functions so that object properties do not have to be accessed directly. The following table highlights the most commonly used functions. Refer to the H file for a complete definition of each API function.

obj_template_t Access Functions

obj_find_template

Find a top-level object template within a module.

obj_find_child

Find the specified child node within a complex object template . Skips over any nodes without names (augment, uses, etc.). Uses the module name that defines the obj_template_t to find a child.

obj_find_child_fast

Find the specified child node within a complex object template . Skips over any nodes without names (augment, uses, etc.). Uses the module namespace ID that to find a child.

obj_first_child

Get the first child node within a complex object template. Skips over any nodes without names.

obj_next_child

Get the next child node after the current specified child. Skips over any nodes without names.

obj_first_terminal_child

Get the first TERMINAL child object within a complex object template. Skips over any nodes without names.

obj_next_terminal_child

Get the next TERMINAL child object within a complex object template. Skips over any nodes without names.

obj_first_terminal_child_nokey

Get the first TERMINAL child object within a complex object template. Skips over any nodes without names and KEY leafs.

obj_next_terminal_child_nokey

Get the next TERMINAL child object within a complex object template. Skips over any nodes without names and KEY leafs.

obj_first_child_augok

Get the first child object within a complex object template. Skips over “refine” and “uses” nodes.

obj_next_child_augok

Get the next child object if the specified object has any children; return augment, not just obj_has_name. Skips over “refine” and “uses” nodes.

obj_first_child_deep

Get the first child node within a complex object template . Skips over any nodes without names, and also any choice and case nodes.

obj_next_child_deep

Get the next child object after the current specified child. Skips over any nodes without names, and also any choice and case nodes.

obj_previous_child

Get the previous child object if the specified object has any children. Skips over any nodes without names.

obj_last_child

Get the LAST child object within a complex object template. Skips over any nodes without names.

obj_find_case

Find the specified case object child object within the specific complex object node.

obj_find_type

Check if a typ_template_t in the obj typedefQ hierarchy.

obj_find_grouping

Check if a grp_template_t in the obj typedefQ hierarchy.

obj_find_key

Find a specific key component by key leaf identifier name.

obj_first_key

Get the first obj_key_t structure for the specified list object type.

obj_next_key

Get the next obj_key_t structure for the specified list object type.

obj_gen_object_id

Allocate and generate the YANG object ID for an object node.

obj_gen_object_id_prefix

Allocate and generate the YANG object ID for an object node. Uses the prefix in every node.

obj_gen_object_id_oid

Allocate and generate the YANG object ID for an object node. Uses the JSON/YANG module-name for prefix convention . Only print module name when namespace changes.

obj_gen_object_id_xpath

Allocate and generate the YANG object ID for an object node. Remove all conceptual choice and case nodes so the resulting string will represent the structure of the value tree for XPath searching.

obj_get_name

Get the object name string.

obj_set_name

Set the name field for this object.

obj_has_name

Return TRUE if the object has a name field.

obj_has_text_content

Return TRUE if the object has text content.

obj_get_status

Get the YANG status for the object.

obj_get_description

Get the YANG description statement for an object. Note that the server will always return a NULL pointer.

obj_get_alt_description

Get the alternate YANG description field for this obj ect. Check if any 'info', then 'help' appinfo nodes present.

obj_get_reference

Get the YANG reference statement for an object. Note that the server will always return a NULL pointer.

obj_get_config_flag

Get the YANG config statement value for an object.

obj_get_max_access

Get the YANG NCX max-access enumeration for an object. Return the explicit value or the inherited value.

obj_get_typestr

Get the name string for the type of an object.

obj_get_default

Get the YANG default value for an object.

obj_get_next_default

Get the next YANG default value for the specified object. Only leaf-list object type is supported.

obj_get_default_case

Get the name of the default case for a choice object.

obj_npcon_has_defaults

Check if the specified NP container has defaults within it. Must be a config object.

obj_get_level

Get the nest level for the specified object . Top-level is '1' . Does not count groupings as a level.

obj_has_typedefs

Check if the object has any nested typedefs in it . This must only be called if the object is defined in a grouping.

obj_get_typdef

Get the internal type definition for the leaf or leaf-list object.

obj_get_basetype

Get the internal base type enumeration for an object.

obj_get_mod_prefix

Get the module prefix for an object.

obj_get_mod_xmlprefix

Get the module prefix (XML format) for this object.

obj_get_mod_name

Get the module name containing an object.

obj_get_mod_version

Get the module revision date for the module containing an object.

obj_in_submodule

Check if the object is defined in a submodule.

obj_get_nsid

Get the internal XML namespace ID for an object.

obj_get_min_elements

Get the YANG min-elements value for a list or leaf-list object.

obj_get_max_elements

Get the YANG max-elements value for a list or leaf-list object.

obj_get_units

Get the YANG units field for a leaf or leaf-list object.

obj_get_parent

Get the parent object node for an object.

obj_get_real_parent

Get the parent object node for an object. Skips over choice and case.

obj_get_presence_string

Get the YANG presence statement for a container object.

obj_get_child_count

Get the number of child nodes for a complex object.

obj_get_fraction_digits

Get the YANG fraction-digits statement for a decimal64 leaf or leaf-list object.

obj_is_anyxml

Return TRUE if the object is YANG anyxml type.

obj_is_anydata

Return TRUE if the object is YANG anydata type.

obj_is_leaf

Return TRUE if the object is YANG leaf type.

obj_is_crypt_hash

Check if the object is a leaf of type crypt-hash. Return TRUE if the object is YANG crypt-hash leaf type.

obj_is_list

Return TRUE if the object is YANG list type.

obj_is_key

Return TRUE if the object is YANG key type.

obj_is_leafy

Return TRUE if the object is YANG leaf or leaf-list type.

obj_get_leaf_list_defset

Get the defset flag for a leaf-list. Return TRUE if leaf-list with original defaults.

obj_find_defval

Find a default for leaf-list. Return TRUE if found.

obj_is_container

Return TRUE if the object is YANG container type.

obj_is_choice

Return TRUE if the object is YANG choice type.

obj_is_case

Return TRUE if the object is YANG case type.

obj_is_uses

Return TRUE if the object is YANG uses type.

obj_is_terminal

Return TRUE if the object is YANG leaf, leaf-list, anyxml, or anydata type.

obj_is_mandatory

Return TRUE if the object is YANG mandatory statement.

obj_is_mandatory_when

Return TRUE if the object is YANG mandatory, but first check if any when statements are FALSE first.

obj_has_when_stmts

Check if any when statements apply to this object . Does not check if they are true, just any when statements present. Return TRUE if object has any when statement associated with it.

obj_is_cloned

Return TRUE if the object is expanded from a grouping or augment statement.

obj_is_augclone

Return TRUE if the object is expanded from an augment statement.

obj_is_augment

Return TRUE if the object is YANG augment statement.

obj_is_external_augment

Check if an object is an external augment. Return TRUE if an augment to another module.

obj_is_external_data_augment

Check if an object is an external augment of a data node. Return TRUE if an augment to data node in another module.

obj_is_refine

Return TRUE if the object is YANG refine statement.

obj_is_data

Check if the object is defined within data or within a notification or RPC instead.

obj_is_data_db

Return TRUE if the object is defined within a YANG database definition.

obj_is_data_node

Return TRUE if the object is a real node type.

obj_is_rpc

Return TRUE if the object is a YANG RPC type.

obj_rpc_has_input

Check if the RPC object has any real input children. Return TRUE if there are any input children.

obj_rpc_has_output

Check if the RPC object has any real output children. Return TRUE if there are any output children.

obj_is_rpcio

Return TRUE if the object is a YANG RPCIO type.

obj_is_action

Return TRUE if the object is a YANG action type.

obj_is_notif

Return TRUE if the object is a YANG notification type.

obj_is_empty

Return TRUE if object is empty of subclauses.

obj_in_rpc

Return TRUE if the object is defined within an RPC statement.

obj_in_notif

Return TRUE if the object is defined within a notification statement.

obj_is_xsdlist

Return TRUE if the object is marked as an XSD list.

obj_is_hidden

Return TRUE if object contains the ncx:hidden extension.

obj_is_root

Return TRUE if object contains the ncx:root extension.

obj_is_password

Return TRUE if object contains the ncx:password extension.

obj_is_cli

Return TRUE if object contains the ncx:cli extension.

obj_is_abstract

Return TRUE if object contains the ncx:abstract extension.

obj_is_xpath_string

Return TRUE if the object is a leaf or leaf-list containing an XPath string.

obj_is_schema_instance_string

Return TRUE if the object is a leaf or leaf-list containing a schema instance identifier string.

obj_is_secure

Return TRUE if object contains the nacm:secure extension.

obj_is_very_secure

Return TRUE if object contains the nacm:very-secure extension.

obj_is_sil_delete_children_first

Check if object is marked as ncx:sil-delete-children-first. Return TRUE if object contains ncx:sil-delete-children-first extension.

obj_is_block_user_create

Check if object is marked as ncx:user-write with create access disabled. Return TRUE if object is marked to block user create access.

obj_is_block_user_update

Check if object is marked as ncx:user-write with update access disabled.

Return TRUE if object is marked to block user update access.

obj_is_block_user_delete

Check if object is marked as ncx:user-write with delete access disabled.

Return TRUE if object is marked to block user delete access.

obj_is_system_ordered

Return TRUE if the list or leaf-list object is system ordered; FALSE if it is user ordered.

obj_is_np_container

Return TRUE if the object is a YANG non presence container.

obj_is_p_container

Return TRUE if the object is a YANG presence container.

obj_is_enabled

Return TRUE if the object is enabled; FALSE if any if-feature, when-stmt, or deviation-stmt has removed the object from the system.

obj_has_iffeature

Return TRUE if object has any if-feature statements.

obj_is_single_instance

Return TRUE if object is a single instance object.

obj_sort_children

Rearrange any child nodes in YANG schema order

obj_is_top

Check if the object is top-level object within the YANG module that defines it. Return TRUE if obj is a top-level object.

obj_is_datapath

Check if object is marked as a ywx:datapath object. Return TRUE if object is marked as datapath.

obj_has_children

Check if there are any accessible nodes within the object. Return TRUE if there are any accessible children.

obj_has_ro_children

Check if there are any accessible read-only child nodes within the object. Return TRUE if there are any accessible read-only children.

obj_has_ro_descendants

Check if there are any accessible read-only descendant nodes within the object. Return TRUE if there are any accessible read-only descendant.

obj_has_rw_children

Check if there are any accessible read-write child nodes within the object. Do not count list keys in this check. Return TRUE if there are any accessible read-write children.

obj_enabled_child_count

Get the count of the number of enabled child nodes for the object template. Returns number of enabled child nodes.

obj_get_keystr

Get the key string for this list object. Returns pointer to key string or NULL if none or not a list.

obj_is_supported

Check an RPC node to check if it is supported or not . It could be disabled at run-time without removing it. Return TRUE if object is supported.

obj_is_dup_local

Check if this object is one that has a duplicate sibling with the same local-name and different module namespace. Return if flagged as duplicate local-name.

obj_is_exclusive_rpc

Return TRUE if exclusive-rpc set; cannot be called by multiple sessions at once.

obj_parent_same_module

Check if the object parent object is the same. Return TRUE if parent from the same module or not sure. Return FALSE if parent not the same module and parent is not root.

obj_set_sil_priority

Set the SIL priority field.

obj_get_sil_priority

Get the SIL priority field.

obj_has_config_defaults

Check if the object itself or child nodes can have a default. Return TRUE if can have a default.

Object Tree Handling Examples

There are various API functions that can be used to locate desired objects. They differ widely by available information that you have prior the search and by desired search precision.

Find Top-Level Object

Find With the Object Name

If the top-level object name is unique, it is safe to find it by just its name.

obj_template_t *ncx_find_any_object(const xmlChar *objname)

Find any top-level object in any YANG module.

Check if an obj_template_t in in any module that matches the object name string

Parameters:

objname -- object name to match

Returns:

pointer to struct if present, NULL otherwise

const xmlChar *objname = (const xmlChar *)"interfaces";
obj_template_t *topobj = ncx_find_any_object(objname);
if (!topobj) {
    res = ERR_NCX_DEF_NOT_FOUND;
}

Find With the Module Pointer

If you know the module where the target object is located, and have the "ncx_module_t" pointer for the module, the following retrieval functions can be used:

obj_template_t *obj_find_template_top(ncx_module_t *mod, const xmlChar *modname, const xmlChar *objname)

Check if an obj_template_t in the mod->datadefQ or any of the include files visible to this module.

Top-level access is not tracked, so the 'test' variable is hard-wired to FALSE

Parameters:
  • mod -- ncx_module to check

  • modname -- module name for the object (needed for augments) (may be NULL to match any 'objname' instance)

  • objname -- object name to find

Returns:

pointer to struct if present, NULL otherwise

In this API function, the "module_name" parameter can be set to NULL.

obj_template_t *topobj =
    obj_find_template_top(mod, module_name, object_name);
if (!topobj) {
    res = ERR_NCX_DEF_NOT_FOUND;
}
obj_template_t *ncx_find_object(ncx_module_t *mod, const xmlChar *objname)

Find a top level module object.

Parameters:
  • mod -- ncx_module to check

  • objname -- object name to find

Returns:

pointer to struct if present, NULL otherwise

obj_template_t *topobj = ncx_find_object(mod, object_name);
if (!topobj) {
    res = ERR_NCX_DEF_NOT_FOUND;
}

Find With the Module Namespace ID

If the module namespace is known, then use this API function.

obj_template_t *ncx_find_object_nsid(xmlns_id_t nsid, const xmlChar *objname)

Find a top level module object by module NSID.

Parameters:
  • nsid -- namespace ID to check

  • objname -- object name

Returns:

pointer to struct if present, NULL otherwise

/* get the top object node using NSID of the OBJ */
obj_template_t *topobj = ncx_find_object_nsid(nsid, object_name);
if (!topobj) {
    res = ERR_NCX_DEF_NOT_FOUND;
}

Access Module Pointer

A module is usually loaded as server boot-time, but it can be loaded at run-time with the <load> or <load-bundle> operations.

The following code illustrates how the module pointer can be obtained during the module load procedure:

status_t ncxmod_load_module(const xmlChar *modname, const xmlChar *revision, dlq_hdr_t *savedevQ, ncx_module_t **retmod)

Determine the location of the specified module and then load it into the system, if not already loaded Main API for this module.

This is the only load module variant that checks if there are any errors recorded in the module or any of its dependencies !!! ONLY RETURNS TRUE IF MODULE AND ALL IMPORTS ARE LOADED OK !!!

Parameters:
  • modname -- module name with no path prefix or file extension

  • revision -- optional revision date of 'modname' to find

  • savedevQ -- Q of ncx_save_deviations_t to use, if any

  • retmod -- [out] address of return module (may be NULL)

    • *retmod pointer to requested module version

Returns:

status

static status_t
     init_function (const xmlChar *modname,
                    const xmlChar *revision)
{

    ncx_module_t *mod = NULL;
    res = ncxmod_load_module(modname,
                             revision,
                             agt_get_savedevQ(),
                             &mod);
    if (res != NO_ERR) {
        return res;
    }

    // the "mod" pointer should be set if res == NO_ERR
}

To locate a module that is already loaded, use the following API function:

ncx_module_t *ncx_find_module(const xmlChar *modname, const xmlChar *revision)

Find a ncx_module_t in the ncx_sesmodQ.

These are the modules that are already loaded Does not look for submodule names if no module name found

Parameters:
  • modname -- module name for the new module

  • revision -- module revision date for the new module (may be NULL)

Returns:

module pointer if found or NULL if not found

// find a specific revision of the module
ncx_module_t *mod = ncx_find_module(modname, revision);
if (mod == NULL) {
    // find any revision of the module
    ncx_module_t *mod = ncx_find_module(modname, NULL);
    if (mod == NULL) {
        res = ERR_NCX_MOD_NOT_FOUND;
    }
}

Match Any Object

The second option to locate a top level object is to search through all the modules and try to match the object name string. The following API functions illustrate how to locate the top level object based on module name:

obj_template_t *ncx_match_any_object(const xmlChar *objname, ncx_name_match_t name_match, boolean alt_names, status_t *retres)

Match any object in any YANG module with extra search options.

Check if an obj_template_t in any module that matches the object name string (objname).

Use name_match to specify the type of name match desired Use alt_names to check objname as the alt-name for the object. This is usually only used in the CLI.

Parameters:
  • objname -- object name to match

  • name_match -- name match mode enumeration

  • alt_names -- TRUE if alternate names should be checked after regular names; FALSE if not

  • retres -- [out] address of return status; *retres return status

Returns:

pointer to struct if present, NULL otherwise

status_t res = NO_ERR;
obj_template_t *topobj =
    ncx_match_any_object(object_name, NCX_MATCH_FIRST, alt_names, &res);

In the above example, the NCX_MATCH_FIRST parameter dictates the API function to stop search on the first match. Alternatively, the parameter can be changed to the following options:

Match Mode

Description

NCX_MATCH_EXACT

Try a case-sensitive exact-length match

NCX_MATCH_EXACT_NOCASE

Try a case-insensitive exact-length match

NCX_MATCH_ONE

Try a case-sensitive partial-name match

NCX_MATCH_ONE_NOCASE

Try a case-insensitive partial-name match

NCX_MATCH_FIRST

Try a case-sensitive first match

NCX_MATCH_FIRST_NOCASE

Try a case-insensitive first match

The 'alt_names' parameter dictates if alternative names should be checked in addition to the YANG node names. If set to TRUE the check will be applied; if set to FALSE the check will be ignored.

The '*res' return parameter may be set to ERR_NCX_MULTIPLE_MATCHES in case there are multiple matching objects available. In this case the function will not return any of the object templates. To search with the highest precision for a specific object. use NCX_MATCH_EXACT value and set alt_names to FALSE.

There is an extended version of the previous API function:

obj_template_t *ncx_match_any_object_ex(const xmlChar *modname, const xmlChar *objname, boolean dataonly, ncx_name_match_t name_match, boolean alt_names, status_t *retres)

Match any object in any YANG module with double extra search options.

Check if an obj_template_t in in any module that matches the object name string; extended parameters

Use name_match to specify the type of name match desired Use alt_names to check objname as the alt-name for the object. This is usually only used in the CLI. Use dataonly to search only for datastore objects

Parameters:
  • modname -- module name of object (may be NULL to search all)

  • objname -- object name to match

  • dataonly -- TRUE for data nodes only; FALSE for any object type

  • name_match -- name match mode enumeration

  • alt_names -- TRUE if alternate names should be checked after regular names; FALSE if not

  • retres -- [out] address of return status; *retres return status

Returns:

pointer to struct if present, NULL otherwise

status_t res = NO_ERR;
obj_template_t *topobj =
     ncx_match_any_object_ex(modname,
                             object_name,
                             dataonly,
                             NCX_MATCH_EXACT,
                             alt_names,
                             &res);

In the above example, the module name is optional; however it is recommended. If it is present the API function will search only within specified module and will not try to search through all the modules.

The 'dataonly' parameter specifies whether the search function should try to match only data nodes. Set to "false" to match any node.

Check For Child Nodes

In order to verify if the current object has any available children, use the following API function:

boolean obj_has_children(obj_template_t *obj)

Check if there are any accessible nodes within the object.

Parameters:

obj -- obj_template to check

Returns:

TRUE if there are any accessible children

FALSE if no datadb child nodes found

boolean has_children = obj_has_children(topobj);

If there are any accessible data nodes within the object the function returns "true".

Find a Specific Child Node

The following example code illustrates how to locate a specific child object of the current top level object. The following API function checks for accessible names only. That means child nodes of choice, case will be present instead of the choice name or case name:

obj_template_t *obj_find_child(obj_template_t *obj, const xmlChar *modname, const xmlChar *objname)

Find a child object with the specified Qname.

This is the main API for finding object child nodes

Parameters:
  • obj -- obj_template_t to check

  • modname -- module name for the object (needed for augments) (may be NULL to match any 'objname' instance)

  • objname -- object name to find

Returns:

pointer to obj_template_t or NULL if not found

/* get the child obj template */
obj_template_t *child_obj = obj_find_child(topobj, modname, objname);

Find Choice or Case Child Node

To locate choice or case objects as well as other accessible names, use the following API function.

This function checks not only for accessible names. That means the choice name or case name will be preferred instead of their child nodes:

obj_template_t *obj_find_child_choice_case(obj_template_t *obj, const xmlChar *modname, const xmlChar *objname)

Find a child object with the specified Qname.

Parameters:
  • obj -- the obj_template_t to check

  • modname -- the module name that defines the obj_template_t if it is NULL and first match will be done, and the module ignored (Name instead of QName)

  • objname -- the object name to find

Returns:

pointer to obj_template_t or NULL if not found

/* get the child obj template */
obj_template_t *child_obj =
    obj_find_child_choice_case(topobj, modname, objname);

There is also an extended version of the previous API function:

obj_template_t *obj_find_child_ex(obj_template_t *obj, const xmlChar *modname, const xmlChar *objname, ncx_name_match_t match_names, boolean alt_names, boolean dataonly, status_t *retres)

Find a child object with the specified Qname extended match modes.

Parameters:
  • obj -- obj_template_t to check

  • modname -- module name for the object (needed for augments) (may be NULL to match any 'objname' instance)

  • objname -- object name to find

  • match_names -- enum for selected match names mode

  • alt_names --

    TRUE if alt-name should be checked in addition to the YANG node name

    FALSE to check YANG names only

  • dataonly --

    TRUE to check just data nodes

    FALSE to check all nodes

  • retres -- [out] address of return status

    • *retres set to return status

Returns:

pointer to struct if present, NULL otherwise

/* get the child obj template */
status_t res = NO_ERR;
obj_template_t *child_obj =
    obj_find_child_ex(topobj,
                      modname,
                      objname,
                      NCX_MATCH_FIRST,
                      alt_names,
                      dataonly,
                      &res);

Object Child Node Traversal

To traverse the child nodes of a parent node (container, list, choice, case), the following set of API functions are used.

To get the first child object of the current object, the following API function can be used. Note, that this function skips over augments and uses:

obj_template_t *obj_first_child(obj_template_t *obj)

Get the first child object if the specified object has any children.

!!!! SKIPS OVER AUGMENT AND USES AND DISABLED OBJECTS !!!!

Parameters:

obj -- obj_template_t to check for children

Returns:

pointer to first child obj_template_t or NULL if not found

obj_template_t *first_obj = obj_first_child(topobj);

Similarly, the following API function can be used to locate the first terminal object. Note, that this function also skips over augments and uses:

obj_template_t *obj_first_terminal_child(obj_template_t *obj)

Get the first child object if the specified object has any children; MUST BE A TERMINAL NODE!!!

!!!! SKIPS OVER AUGMENT AND USES AND DISABLED OBJECTS !!!!

Parameters:

obj -- obj_template_t to check for children

Returns:

pointer to first child obj_template_t or NULL if not found

obj_template_t *first_obj = obj_first_terminal_child(topobj);

In order to get the next, the last, parent or previous child object or the terminal child object the following API functions can be used:

obj_template_t *obj_next_child(obj_template_t *obj)

Get the next child object if the specified object has any children.

!!!! SKIPS OVER AUGMENT AND USES !!!!

Parameters:

obj -- obj_template_t to check

Returns:

pointer to next child obj_template_t or NULL if not found

obj_template_t *next_obj = obj_next_child(first_obj);
obj_template_t *obj_next_terminal_child(obj_template_t *obj)

Get the next child object if the specified object has any children; MUST BE TERMINAL NODE!!

!!!! SKIPS OVER AUGMENT AND USES !!!!

Parameters:

obj -- obj_template_t to check

Returns:

pointer to next terminal child obj_template_t or NULL if not found

obj_template_t *next_obj = obj_next_terminal_child(first_obj);
obj_template_t *obj_previous_child(obj_template_t *obj)

Get the previous child object if the specified object has any children.

!!!! SKIPS OVER AUGMENT AND USES !!!!

Parameters:

obj -- obj_template_t to check

Returns:

pointer to previous child obj_template_t or NULL if not found

obj_template_t *prev_obj = obj_previous_child(next_obj);
obj_template_t *obj_last_child(obj_template_t *obj)

Get the last child object if the specified object has any children.

!!!! SKIPS OVER AUGMENT AND USES !!!!

Parameters:

obj -- obj_template_t to check

Returns:

pointer to last child obj_template_t or NULL if not found

obj_template_t *last_obj = obj_last_child(topobj);
obj_template_t *obj_get_parent(obj_template_t *obj)

Get the parent of the current object.

Parameters:

obj -- object to check

Returns:

pointer to the parent of this object or NULL if none

obj_template_t *topobj = obj_get_parent(next_obj);

The following example shows how the child object nodes can be traversed in forward order:

/* check all the child nodes forward */
obj_template_t *chobj = obj_first_child(obj);
for (; chobj; chobj = obj_next_child(chobj)) {

    const xmlChar *modname = obj_get_mod_name(chobj);
    const xmlChar *objname = obj_get_name(chobj);

    /* process objects here */

}

The following example shows how the child object nodes can be traversed in reverse order:

/* check all the child nodes reverse */
obj_template_t *chobj = obj_last_child(obj);
for (; chobj; chobj = obj_prev_child(chobj)) {

    const xmlChar *modname = obj_get_mod_name(chobj);
    const xmlChar *objname = obj_get_name(chobj);

    /* process objects here */

}

Process Ancestor Nodes

In order to loop through ancestor entries and process them as required, the following code may be used:

boolean obj_is_root(const obj_template_t *obj)

Check if object is marked as a root object.

Parameters:

obj -- obj_template to check

Returns:

TRUE if object is marked as ncx:root; FALSE if not

/* go through the ancestor entries and process them as needed */
obj_template_t *testobj = obj_get_parent(chobj);
while (testobj) {
    /* process parent objects here */
    testobj = obj_get_parent(testobj);
    if (testobj && obj_is_root(testobj)) {
        testobj = NULL;
    }
}

The 'obj_is_root' API function signals when to stop. It is also possible to have a NULL pointer returned. That indicates you reached the top root container. This container must not be modified, accessed or changed in any manner.