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
-
enumerator OBJ_TYP_NONE
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
-
dlq_hdr_t qhdr
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 Usealt_names
to checkobjname
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 |
---|---|
|
Try a case-sensitive exact-length match |
|
Try a case-insensitive exact-length match |
|
Try a case-sensitive partial-name match |
|
Try a case-insensitive partial-name match |
|
Try a case-sensitive first match |
|
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 Usealt_names
to checkobjname
as the alt-name for the object. This is usually only used in the CLI. Usedataonly
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.