### Add Nodes to Data Tree Source: https://context7.com/cesnet/libyang-cpp/llms.txt Adds child nodes to an existing DataNode tree using YANG schema paths. Use `newPath` for simple additions or `newPath2` to get references to the created parent and target node. Can also merge other data trees. ```cpp // Build a tree incrementally. auto root = ctx.newPath("/example-schema:person[name='Alice']"); root.newPath("/example-schema:person[name='Alice']/age", "30"); // newPath2 returns the first created parent and the target node. auto created = root.newPath2( "/example-schema:person[name='Bob']/age", "25" ); std::cout << created.createdParent->path() << "\n"; // /example-schema:person[name='Bob'] std::cout << created.createdNode->path() << "\n"; // /example-schema:person[name='Bob']/age // Merge another tree into this one. auto extra = ctx.parseData(moreJson, libyang::DataFormat::JSON); root.merge(*extra); ``` -------------------------------- ### Create and Configure libyang Context Source: https://context7.com/cesnet/libyang-cpp/llms.txt Instantiate a libyang context, optionally specifying search paths and context options. This is the entry point for all libyang operations. ```cpp #include #include // Create a context pointing at the built-in module directory, // without loading the YANG library module and ignoring the CWD. libyang::Context ctx( libyang::internalModuleDirectory(), libyang::ContextOptions::NoYangLibrary | libyang::ContextOptions::DisableSearchCwd ); // Add an extra search path for user-provided YANG files. ctx.setSearchDir("/usr/share/yang/modules/ietf"); // List every module already loaded in the context. for (const auto& mod : ctx.modules()) { std::cout << mod.name(); if (mod.revision()) std::cout << "@" << *mod.revision(); std::cout << " ns=" << mod.ns() << " implemented=" << mod.implemented() << "\n"; } // Example output: // ietf-inet-types ns=urn:ietf:params:xml:ns:yang:ietf-inet-types implemented=0 // yang ns=urn:ietf:params:xml:ns:yang:1 implemented=1 // ... ``` -------------------------------- ### Build libyang-cpp with CMake Source: https://github.com/cesnet/libyang-cpp/blob/master/README.md Standard CMake build process for the libyang-cpp library. Ensure you are in the build directory before running these commands. ```bash mkdir build cd build cmake .. make make install ``` -------------------------------- ### Configure Global Logging with libyang::setLogLevel and setLogOptions Source: https://context7.com/cesnet/libyang-cpp/llms.txt Globally control libyang message output levels and storage behavior. Use `libyang::setLogLevel` to set the message verbosity and `libyang::setLogOptions` to manage how errors are logged or stored in the context. ```cpp #include // Set log level; returns the previous level. auto prev = libyang::setLogLevel(libyang::LogLevel::Warning); // LogLevel options: Error, Warning, Verbose, Debug // Control log storage behavior. libyang::setLogOptions( libyang::LogOptions::Log // print to stderr | libyang::LogOptions::Store // store all errors in the context ); // Store only the last error (smaller memory footprint). libyang::setLogOptions(libyang::LogOptions::Log | libyang::LogOptions::StoreLast); // Suppress all output. libyang::setLogOptions(libyang::LogOptions::NoLog); // Restore previous log level. libyang::setLogLevel(prev); ``` -------------------------------- ### Parse Data from File with Options Source: https://context7.com/cesnet/libyang-cpp/llms.txt Parses an instance data document from a file, supporting various options like Strict parsing and NoState validation. Supports XML format. ```cpp auto root2 = ctx.parseData( std::filesystem::path{"data.xml"}, libyang::DataFormat::XML, libyang::ParseOptions::Strict, libyang::ValidationOptions::NoState ); ``` -------------------------------- ### Navigate Data Tree with findPath and findXPath Source: https://context7.com/cesnet/libyang-cpp/llms.txt Use `findPath` for exact path matching and `findXPath` for XPath queries on a data tree rooted at a `DataNode`. `findPath` returns an `std::optional`, while `findXPath` returns a `Set`. These methods are useful for locating specific nodes within a parsed data structure. ```cpp auto root = ctx.parseData(json, libyang::DataFormat::JSON); // Exact path, returns std::optional. auto leaf = root->findPath("/example-schema:leafInt32"); if (leaf) { std::cout << leaf->path() << "\n"; // /example-schema:leafInt32 std::cout << leaf->asTerm().valueStr() << "\n"; // 420 } // XPath returns a Set. auto nodes = root->findXPath("/example-schema:person[name='Dan']"); for (const auto& n : nodes) { std::cout << n.path() << "\n"; // /example-schema:person[name='Dan'] } // Returns nullopt when the node is absent (not an error). auto absent = root->findPath("/example-schema:active"); assert(!absent.has_value()); ``` -------------------------------- ### Context::loadModule Source: https://context7.com/cesnet/libyang-cpp/llms.txt Loads a YANG module by name from the configured search path, optionally specifying a revision and features. ```APIDOC ## Context::loadModule — load a module by name from the search path ### Description Finds a YANG module by name (and optional revision) in the configured search directories and loads it into the context. ### Method `ctx.loadModule(module_name, revision, features)` ### Parameters #### Path Parameters - **module_name** (std::string) - The name of the module to load. - **revision** (std::optional) - Optional - The specific revision of the module to load. - **features** (std::vector) - Optional - A list of features to enable. Use `{"*"}` to enable all features. ### Request Example ```cpp ctx.setSearchDir("/usr/share/yang/modules"); // Load the latest revision with specific features. auto mod = ctx.loadModule("ietf-interfaces", std::nullopt, {"arbitrary-names"}); std::cout << mod.name() << "\n"; // ietf-interfaces std::cout << *mod.revision() << "\n"; // 2018-02-20 // Load a specific revision. auto mod2 = ctx.loadModule("ietf-netconf", "2011-06-01"); // Load with all features using the wildcard. auto mod3 = ctx.loadModule("mod1", std::nullopt, {"*"}); // Throws if the module is not found. try { ctx.loadModule("no-such-module"); } catch (const libyang::Error& e) { std::cerr << e.what() << "\n"; } ``` ``` -------------------------------- ### Load YANG Module by Name Source: https://context7.com/cesnet/libyang-cpp/llms.txt Load a YANG module by name and optional revision from the configured search directories. Features can be specified, including enabling all features with '*'. Throws an error if the module is not found. ```cpp ctx.setSearchDir("/usr/share/yang/modules"); // Load the latest revision with specific features. auto mod = ctx.loadModule("ietf-interfaces", std::nullopt, {"arbitrary-names"}); std::cout << mod.name() << "\n"; // ietf-interfaces std::cout << *mod.revision() << "\n"; // 2018-02-20 // Load a specific revision. auto mod2 = ctx.loadModule("ietf-netconf", "2011-06-01"); // Load with all features using the wildcard. auto mod3 = ctx.loadModule("mod1", std::nullopt, {"*"}); // Throws if the module is not found. try { ctx.loadModule("no-such-module"); } catch (const libyang::Error& e) { std::cerr << e.what() << "\n"; } ``` -------------------------------- ### Create RPC Output Leaf Source: https://context7.com/cesnet/libyang-cpp/llms.txt Creates a leaf node specifically for an RPC output, using the `CreationOptions::Output` flag. ```cpp // Create an RPC output leaf. auto rpcOut = ctx.newPath( "/example-schema:myRpc/outputLeaf", "ok", libyang::CreationOptions::Output ); ``` -------------------------------- ### Register Module Callback for Dynamic Loading Source: https://context7.com/cesnet/libyang-cpp/llms.txt Register a callback to dynamically supply missing YANG modules. The callback receives the module name and optionally returns the module content. ```cpp ctx.registerModuleCallback( [](const std::string& modName, const std::optional& /*revision*/, const std::optional& /*submodName*/, const std::optional& /*submodRev*/) -> std::optional { if (modName == "my-module") { return libyang::ModuleInfo{ .data = my_yang_string, // std::string with YANG text .format = libyang::SchemaFormat::YANG }; } return std::nullopt; // cannot supply this module } ); // Now loading "my-module" will trigger the callback. auto mod = ctx.loadModule("my-module"); ``` -------------------------------- ### Context::parseModule Source: https://context7.com/cesnet/libyang-cpp/llms.txt Loads a YANG or YIN schema from a string or file into the context, optionally enabling specific features. ```APIDOC ## Context::parseModule — load a YANG or YIN schema from a string or file ### Description Parses a YANG or YIN module into the context and returns a `Module` handle. Optionally enables a subset of YANG features. ### Method `ctx.parseModule(schema_data, schema_format, features)` ### Parameters #### Path Parameters - **schema_data** (std::string or std::filesystem::path) - The YANG or YIN schema content or file path. - **schema_format** (libyang::SchemaFormat) - The format of the schema (YANG or YIN). - **features** (std::vector) - Optional - A list of features to enable. ### Request Example ```cpp const std::string yang = R"( module my-net { namespace "http://example.com/my-net"; prefix mn; feature ipv6-support; leaf hostname { type string; } leaf ipv6-enabled { if-feature "ipv6-support"; type boolean; default false; } } )"; // Parse from string, enabling a specific feature. auto mod = ctx.parseModule(yang, libyang::SchemaFormat::YANG, {"ipv6-support"}); std::cout << mod.name() << "\n"; // my-net std::cout << mod.featureEnabled("ipv6-support") << "\n"; // 1 // Parse from a file path. auto mod2 = ctx.parseModule( std::filesystem::path{"/usr/share/yang/ietf-interfaces@2018-02-20.yang"}, libyang::SchemaFormat::YANG, {"*"} // enable ALL features ); // Parse YIN format. auto mod3 = ctx.parseModule(yin_string, libyang::SchemaFormat::YIN); // Throws std::runtime_error on invalid schema. try { ctx.parseModule("garbage", libyang::SchemaFormat::YANG); } catch (const libyang::Error& e) { std::cerr << e.what() << "\n"; // Can't parse module: LY_EVALID } ``` ``` -------------------------------- ### Fixed-Point Arithmetic with libyang::Decimal64 Source: https://context7.com/cesnet/libyang-cpp/llms.txt Utilize a compile-time-safe `decimal64` type for fixed-point arithmetic, supporting conversions to `double` and `std::string`. Requires including `` and using `libyang::literals`. ```cpp #include using namespace libyang::literals; // Literal construction. auto d1 = 123.456_decimal64; // 3 fraction digits auto d2 = 12.34_decimal64; // 2 fraction digits // From raw integer scaled by 10^digits. auto d3 = libyang::Decimal64::fromRawDecimal<2>(1234); // == 12.34 // From double (rounded). auto d4 = libyang::Decimal64::fromDouble<3>(3.14159); // 3.142 // Convert to double. double d = static_cast(d1); // 123.456 // Convert to string. std::string s = std::string(d1); // "123.456" std::cout << s << "\n"; // Arithmetic negation. auto neg = -d1; std::cout << std::string(neg) << "\n"; // "-123.456" // Comparison. static_assert(12.34_decimal64 == libyang::Decimal64::fromRawDecimal<2>(1234)); ``` -------------------------------- ### Parse YANG/YIN Schema from String or File Source: https://context7.com/cesnet/libyang-cpp/llms.txt Load YANG or YIN schema modules into the context from a string or file path. Features can be optionally enabled during parsing. Handles errors by throwing std::runtime_error. ```cpp const std::string yang = R"( module my-net { namespace "http://example.com/my-net"; prefix mn; feature ipv6-support; leaf hostname { type string; } leaf ipv6-enabled { if-feature "ipv6-support"; type boolean; default false; } } )"; // Parse from string, enabling a specific feature. auto mod = ctx.parseModule(yang, libyang::SchemaFormat::YANG, {"ipv6-support"}); std::cout << mod.name() << "\n"; // my-net std::cout << mod.featureEnabled("ipv6-support") << "\n"; // 1 // Parse from a file path. auto mod2 = ctx.parseModule( std::filesystem::path{"/usr/share/yang/ietf-interfaces@2018-02-20.yang"}, libyang::SchemaFormat::YANG, {"*"} // enable ALL features ); // Parse YIN format. auto mod3 = ctx.parseModule(yin_string, libyang::SchemaFormat::YIN); // Throws std::runtime_error on invalid schema. try { ctx.parseModule("garbage", libyang::SchemaFormat::YANG); } catch (const libyang::Error& e) { std::cerr << e.what() << "\n"; // Can't parse module: LY_EVALID } ``` -------------------------------- ### wrapRawNode / releaseRawNode / createUnmanagedContext Source: https://context7.com/cesnet/libyang-cpp/llms.txt These functions facilitate C interoperability by allowing the wrapping and unwrapping of raw libyang C API objects into managed C++ objects and vice versa, ensuring RAII safety in the C++ layers. ```APIDOC ## wrapRawNode / releaseRawNode / createUnmanagedContext ### Description Escape hatches for integrating libyang-cpp with existing code that uses the raw libyang C API. ### Functions - **wrapRawNode** - Wraps a raw `lyd_node*` obtained from C code into a managed `libyang::DataNode`. - **Usage:** `libyang::DataNode managed = libyang::wrapRawNode(raw);` - **releaseRawNode** - Releases ownership of a `libyang::DataNode` back to the C API, returning a raw `lyd_node*`. The caller is responsible for freeing the returned pointer. - **Usage:** `lyd_node* released = libyang::releaseRawNode(std::move(managed));` - **createUnmanagedContext** - Wraps a raw `ly_ctx*` with a custom deleter, allowing it to be managed by libyang-cpp without taking ownership or performing default cleanup. - **Usage:** `libyang::Context ctx = libyang::createUnmanagedContext(rawCtx, [](ly_ctx* c) { /* custom cleanup */ });` - **retrieveContext** - Retrieves the raw `ly_ctx*` from a `libyang::Context` wrapper. - **Usage:** `ly_ctx* back = libyang::retrieveContext(ctx);` ### Example Usage ```cpp #include #include #include // Wrap a raw lyd_node* obtained from C code into a managed DataNode. lyd_node* raw = /* obtained from C API */; libyang::DataNode managed = libyang::wrapRawNode(raw); // Release ownership back to C (caller must free). lyd_node* released = libyang::releaseRawNode(std::move(managed)); // Wrap a raw ly_ctx* with a custom deleter. ly_ctx* rawCtx = /* obtained from sysrepo or some other C library */; libyang::Context ctx = libyang::createUnmanagedContext( rawCtx, [](ly_ctx* c) { /* custom cleanup, e.g. do nothing */ } ); // Retrieve the raw ly_ctx* from a Context wrapper. ly_ctx* back = libyang::retrieveContext(ctx); ``` ``` -------------------------------- ### Work with YANG Identities using Module::identities and Identity::derived Source: https://context7.com/cesnet/libyang-cpp/llms.txt Enumerates all identities defined in a module and navigates the identity inheritance hierarchy. Supports recursive derivation and use in standard containers like std::set with custom comparators. ```cpp auto mod = ctx.parseModule(example_schema, libyang::SchemaFormat::YANG); auto identities = mod.identities(); // identities: food, fruit, pizza, hawaii for (const auto& id : identities) { std::cout << id.name() << " (module: " << id.module().name() << ")\n"; for (const auto& derived : id.derived()) { std::cout << " -> " << derived.name() << "\n"; } } // All transitive derivatives. auto food = identities[0]; for (const auto& d : food.derivedRecursive()) { std::cout << d.name() << "\n"; // fruit, pizza, hawaii } // Use SomeOrder for storing identities in a std::set. std::set idSet; for (const auto& id : identities) idSet.insert(id); ``` -------------------------------- ### Print Module in YANG/YIN/Tree Format with Module::printStr Source: https://context7.com/cesnet/libyang-cpp/llms.txt Serializes a loaded and compiled module to a human-readable string in YANG source, compiled YANG, YIN, or tree-diagram format. Useful for debugging or displaying schema information. ```cpp auto mod = ctx.parseModule(yang, libyang::SchemaFormat::YANG); // ASCII tree diagram. std::string tree = mod.printStr(libyang::SchemaOutputFormat::Tree); std::cout << tree; // module: my-net // +--rw hostname? string // +--rw ipv6-enabled? boolean // YANG source (reformatted). std::string yangOut = mod.printStr(libyang::SchemaOutputFormat::Yang); // Compiled YANG (with resolved groupings, augments, etc.). std::string compiled = mod.printStr(libyang::SchemaOutputFormat::CompiledYang); // YIN (XML encoding of YANG). std::string yin = mod.printStr(libyang::SchemaOutputFormat::Yin); ``` -------------------------------- ### Validate Data Trees with validateAll and validateOp Source: https://context7.com/cesnet/libyang-cpp/llms.txt Validate a complete data tree against the loaded schema using `validateAll`, or validate an RPC operation tree against an optional datastore tree using `validateOp`. Both functions throw `libyang::ErrorWithCode` on failure. Requires including ``. ```cpp #include // Full data-tree validation. auto data = ctx.parseData(json, libyang::DataFormat::JSON, libyang::ParseOptions::ParseOnly); try { libyang::validateAll(data, libyang::ValidationOptions::NoState); std::cout << "Valid\n"; } catch (const libyang::ErrorWithCode& e) { std::cerr << "Validation failed: " << e.what() << "\n"; } // Validate an RPC operation against an optional datastore tree. auto pop = ctx.parseOp(rpcJson, libyang::DataFormat::JSON, libyang::OperationType::RpcYang); std::optional datastoreTree = std::nullopt; libyang::validateOp(*pop.op, datastoreTree, libyang::OperationType::RpcYang); ``` -------------------------------- ### Inspect and Clear libyang Errors Source: https://context7.com/cesnet/libyang-cpp/llms.txt After an operation that might fail, use `getErrors` to retrieve a list of `ErrorInfo` structs, each detailing the error code, message, and path. Ensure logging is enabled with `setLogOptions` before operations that may throw. Use `cleanAllErrors` to clear the error list. ```cpp libyang::setLogOptions(libyang::LogOptions::Log | libyang::LogOptions::Store); try { ctx.newPath("/example-schema:leafInt8", "9001"); // out of int8 range } catch (const libyang::ErrorWithCode& e) { std::cerr << "Error code: " << e.code() << "\n"; } for (const auto& err : ctx.getErrors()) { std::cout << "level=" << err.level << " code=" << err.code << " msg=" << err.message; if (err.schemaPath) std::cout << " at=" << *err.schemaPath; std::cout << "\n"; } // level=Error code=ValidationFailure msg=Value "9001" is out of type int8 min/max bounds. at=/example-schema:leafInt8 ctx.cleanAllErrors(); std::cout << ctx.getErrors().size() << "\n"; // 0 ``` -------------------------------- ### Wrap Raw libyang C Nodes and Contexts Source: https://context7.com/cesnet/libyang-cpp/llms.txt Use `wrapRawNode` to manage raw `lyd_node*` from C code within libyang-cpp's RAII system. `releaseRawNode` returns ownership to the caller, who must then manage the memory. `createUnmanagedContext` wraps a raw `ly_ctx*` with a custom deleter, useful for contexts managed by other libraries. ```cpp #include #include #include // Wrap a raw lyd_node* obtained from C code into a managed DataNode. lyd_node* raw = /* obtained from C API */; libyang::DataNode managed = libyang::wrapRawNode(raw); // Release ownership back to C (caller must free). lyd_node* released = libyang::releaseRawNode(std::move(managed)); // Wrap a raw ly_ctx* with a custom deleter. ly_ctx* rawCtx = /* obtained from sysrepo or some other C library */; libyang::Context ctx = libyang::createUnmanagedContext( rawCtx, [](ly_ctx* c) { /* custom cleanup, e.g. do nothing */ } ); // Retrieve the raw ly_ctx* from a Context wrapper. ly_ctx* back = libyang::retrieveContext(ctx); ``` -------------------------------- ### Context::newPath / Context::newPath2 Source: https://context7.com/cesnet/libyang-cpp/llms.txt Creates new data nodes within the context using YANG schema paths. `newPath` creates a single node, while `newPath2` returns both the created parent and the leaf node, facilitating the creation of nested structures. ```APIDOC ## `Context::newPath` / `Context::newPath2` — create data nodes by schema path Creates a new data node tree by specifying a YANG schema path and an optional value. `newPath2` additionally returns both the first created parent and the leaf node itself via `CreatedNodes`. ```cpp ctx.parseModule(yang, libyang::SchemaFormat::YANG); // Create a single leaf node. auto leaf = ctx.newPath("/my-net:hostname", "router-1.example.com"); std::cout << leaf.path() << "\n"; // /my-net:hostname // Create nested nodes — parent containers are auto-created. auto [parent, node] = [&]{ auto created = ctx.newPath2("/my-net:interfaces/interface/name", "eth0"); return std::make_pair(created.createdParent, created.createdNode); }(); // parent->path() == /my-net:interfaces // node->path() == /my-net:interfaces/interface[name='eth0']/name // Create an RPC output leaf. auto rpcOut = ctx.newPath( "/example-schema:myRpc/outputLeaf", "ok", libyang::CreationOptions::Output ); ``` ``` -------------------------------- ### Traverse Schema Trees with childrenDfs, childInstantiables, and immediateChildren Source: https://context7.com/cesnet/libyang-cpp/llms.txt Iterates over compiled schema nodes depth-first, or only over direct instantiable children. Use `childInstantiables` to skip `choice`/`case` wrappers, and `immediateChildren` to include them. ```cpp auto modSchema = ctx.getModule("type_module", std::nullopt); // Iterate over all instantiable children of a module (flattening choice/case). for (const auto& child : modSchema->childInstantiables()) { std::cout << child.name() << " : " << child.path() << "\n"; } // DFS over an entire module's schema subtree. for (const auto& node : modSchema->childrenDfs()) { std::cout << std::string(/* depth */ 2, ' ') << node.name() << "\n"; } // Direct children of a schema node (includes choice/case nodes). auto list = ctx.findPath("/type_module:listAdvancedWithTwoKey"); for (const auto& child : list.immediateChildren()) { std::cout << child.name() << "\n"; // lol, notKey1, notKey2, notKey3, notKey4 } ``` -------------------------------- ### YANG-flavored Regex Matching with libyang::Regex Source: https://context7.com/cesnet/libyang-cpp/llms.txt Compile and match patterns using the YANG-flavored regex engine, identical to the one used for `pattern` constraints. Requires including ``. ```cpp #include libyang::Regex re("[a-z][a-z0-9\\-]*"); std::cout << re.matches("router-1") << "\n"; // 1 std::cout << re.matches("Router-1") << "\n"; // 0 (uppercase) std::cout << re.matches("123abc") << "\n"; // 0 (starts with digit) // Matches YANG phone-number pattern. libyang::Regex phone("\\+[0-9]{1,3}-[0-9]{3,14}"); std::cout << phone.matches("+1-5551234567") << "\n"; // 1 ``` -------------------------------- ### Control YANG Features with Module::features and setImplemented Source: https://context7.com/cesnet/libyang-cpp/llms.txt Inspect all features of a module, check their enabled state, and enable specific features or all features on-the-fly. `setImplemented` without arguments re-marks current features as implemented. ```cpp auto mod = ctx.loadModule("mod1", std::nullopt, {}); // no features enabled initially // Inspect all features. for (const auto& f : mod.features()) { std::cout << f.name() << ": " << (f.isEnabled() ? "on" : "off") << "\n"; } // Enable a specific subset. mod.setImplemented({"feature1", "feature2"}); std::cout << mod.featureEnabled("feature1") << "\n"; // 1 std::cout << mod.featureEnabled("feature3") << "\n"; // 0 // Enable everything. mod.setImplemented(libyang::AllFeatures{}); std::cout << mod.featureEnabled("feature3") << "\n"; // 1 // setImplemented without args keeps current features but re-marks as implemented. mod.setImplemented(); ``` -------------------------------- ### libyang::Context Source: https://context7.com/cesnet/libyang-cpp/llms.txt Represents the libyang context, serving as the entry point for all libyang operations and managing object lifetimes. ```APIDOC ## libyang::Context — create and configure a libyang context ### Description `Context` is the entry point for all libyang operations. It wraps `ly_ctx` and manages the lifetimes of all objects derived from it. Constructing a `Context` optionally takes a search-path for YANG files and a set of `ContextOptions` flags. ### Method `libyang::Context(search_path, context_options)` ### Parameters #### Path Parameters - **search_path** (std::string) - Optional - Path for YANG files. - **context_options** (libyang::ContextOptions) - Optional - Flags for context configuration. ### Example ```cpp #include #include // Create a context pointing at the built-in module directory, // without loading the YANG library module and ignoring the CWD. libyang::Context ctx( libyang::internalModuleDirectory(), libyang::ContextOptions::NoYangLibrary | libyang::ContextOptions::DisableSearchCwd ); // Add an extra search path for user-provided YANG files. ctx.setSearchDir("/usr/share/yang/modules/ietf"); // List every module already loaded in the context. for (const auto& mod : ctx.modules()) { std::cout << mod.name(); if (mod.revision()) std::cout << "@" << *mod.revision(); std::cout << " ns=" << mod.ns() << " implemented=" << mod.implemented() << "\n"; } // Example output: // ietf-inet-types ns=urn:ietf:params:xml:ns:yang:ietf-inet-types implemented=0 // yang ns=urn:ietf:params:xml:ns:yang:1 implemented=1 // ... ``` ``` -------------------------------- ### Find RPC Output Node Source: https://context7.com/cesnet/libyang-cpp/llms.txt Finds an RPC output node by its path, requiring the `InputOutputNodes::Output` flag to be specified. ```cpp // RPC output nodes require the Output flag. auto outputNode = ctx.findPath( "/example-schema:myRpc/outputLeaf", libyang::InputOutputNodes::Output ); ``` -------------------------------- ### Module::features / setImplemented Source: https://context7.com/cesnet/libyang-cpp/llms.txt Control YANG features for a module. Lists all features, checks their enabled state, and enables selected features on-the-fly. ```APIDOC ## Module::features / setImplemented — control YANG features Lists all features of a module, checks their enabled state, and enables selected features on-the-fly via `setImplemented`. ```cpp auto mod = ctx.loadModule("mod1", std::nullopt, {}); // no features enabled initially // Inspect all features. for (const auto& f : mod.features()) { std::cout << f.name() << ": " << (f.isEnabled() ? "on" : "off") << "\n"; } // Enable a specific subset. mod.setImplemented({"feature1", "feature2"}); std::cout << mod.featureEnabled("feature1") << "\n"; // 1 std::cout << mod.featureEnabled("feature3") << "\n"; // 0 // Enable everything. mod.setImplemented(libyang::AllFeatures{}); std::cout << mod.featureEnabled("feature3") << "\n"; // 1 // setImplemented without args keeps current features but re-marks as implemented. mod.setImplemented(); ``` ``` -------------------------------- ### Create Nested Nodes with newPath2 Source: https://context7.com/cesnet/libyang-cpp/llms.txt Creates nested data nodes, automatically creating parent containers. `newPath2` returns both the created parent and the leaf node. ```cpp // Create nested nodes — parent containers are auto-created. auto [parent, node] = [&]{ auto created = ctx.newPath2("/my-net:interfaces/interface/name", "eth0"); return std::make_pair(created.createdParent, created.createdNode); }(); // parent->path() == /my-net:interfaces // node->path() == /my-net:interfaces/interface[name='eth0']/name ``` -------------------------------- ### Parse Data from JSON or XML String Source: https://context7.com/cesnet/libyang-cpp/llms.txt Parses an instance data document from a string into a DataNode tree. Returns std::nullopt if the document is empty but syntactically valid. Supports JSON and XML formats. ```cpp const std::string json = R"({ "example-schema:leafInt32": 420, "example-schema:first": { "second": { "third": { "fourth": {} } } } })"; // Parse from a string. auto root = ctx.parseData(json, libyang::DataFormat::JSON); if (root) { std::cout << root->path() << "\n"; // /example-schema:leafInt32 } ``` -------------------------------- ### libyang::Regex Source: https://context7.com/cesnet/libyang-cpp/llms.txt Compiles and matches patterns using the YANG-flavored regex engine, the same engine used by libyang for `pattern` constraints. ```APIDOC ## libyang::Regex — YANG-flavored regular expression matching Compiles and matches patterns using the YANG-flavored (POSIX-like with Unicode extensions) regex engine, the same engine used by libyang for `pattern` constraints. ```cpp #include libyang::Regex re("[a-z][a-z0-9\\-]*"); std::cout << re.matches("router-1") << "\n"; // 1 std::cout << re.matches("Router-1") << "\n"; // 0 (uppercase) std::cout << re.matches("123abc") << "\n"; // 0 (starts with digit) // Matches YANG phone-number pattern. libyang::Regex phone("\\+[0-9]{1,3}-[0-9]{3,14}"); std::cout << phone.matches("+1-5551234567") << "\n"; // 1 ``` ``` -------------------------------- ### Find Schema Node by Exact Path Source: https://context7.com/cesnet/libyang-cpp/llms.txt Locates a compiled schema node by its exact data path. Throws `libyang::Error` if the node is not found. Returns a `SchemaNode` object. ```cpp // Exact path lookup — throws libyang::Error if not found. auto schemaLeaf = ctx.findPath("/example-schema:leafInt8"); std::cout << schemaLeaf.name() << "\n"; // leafInt8 std::cout << schemaLeaf.path() << "\n"; // /example-schema:leafInt8 std::cout << (int)schemaLeaf.nodeType() << "\n"; // NodeType::Leaf ``` -------------------------------- ### libyang::setLogLevel / setLogOptions Source: https://context7.com/cesnet/libyang-cpp/llms.txt Globally controls which libyang messages are emitted and how errors are stored for later retrieval via `Context::getErrors`. ```APIDOC ## libyang::setLogLevel / setLogOptions — configure global logging Globally controls which libyang messages are emitted and how errors are stored for later retrieval via `Context::getErrors`. ```cpp #include // Set log level; returns the previous level. auto prev = libyang::setLogLevel(libyang::LogLevel::Warning); // LogLevel options: Error, Warning, Verbose, Debug // Control log storage behavior. libyang::setLogOptions( libyang::LogOptions::Log // print to stderr | libyang::LogOptions::Store // store all errors in the context ); // Store only the last error (smaller memory footprint). libyang::setLogOptions(libyang::LogOptions::Log | libyang::LogOptions::StoreLast); // Suppress all output. libyang::setLogOptions(libyang::LogOptions::NoLog); // Restore previous log level. libyang::setLogLevel(prev); ``` ``` -------------------------------- ### Create Single Leaf Node Source: https://context7.com/cesnet/libyang-cpp/llms.txt Creates a single leaf data node using its schema path. The parent container is automatically created if it does not exist. ```cpp ctx.parseModule(yang, libyang::SchemaFormat::YANG); // Create a single leaf node. auto leaf = ctx.newPath("/my-net:hostname", "router-1.example.com"); std::cout << leaf.path() << "\n"; // /my-net:hostname ``` -------------------------------- ### Module::identities / Identity::derived Source: https://context7.com/cesnet/libyang-cpp/llms.txt Works with YANG identities by enumerating all identities defined in a module and navigating the identity inheritance hierarchy. ```APIDOC ## Module::identities / Identity::derived ### Description Enumerates all identities defined in a module and navigates the identity inheritance hierarchy. ### Usage ```cpp auto mod = ctx.parseModule(example_schema, libyang::SchemaFormat::YANG); auto identities = mod.identities(); // identities: food, fruit, pizza, hawaii for (const auto& id : identities) { std::cout << id.name() << " (module: " << id.module().name() << ")\n"; for (const auto& derived : id.derived()) { std::cout << " -> " << derived.name() << "\n"; } } // All transitive derivatives. auto food = identities[0]; for (const auto& d : food.derivedRecursive()) { std::cout << d.name() << "\n"; // fruit, pizza, hawaii } // Use SomeOrder for storing identities in a std::set. std::set idSet; for (const auto& id : identities) idSet.insert(id); ``` ``` -------------------------------- ### Retrieve Loaded Modules using Context Source: https://context7.com/cesnet/libyang-cpp/llms.txt Use `getModule`, `getModuleImplemented`, or `getModuleLatest` on a `Context` object to find loaded YANG modules by name and optional revision. `getModuleImplemented` specifically targets modules that are implemented, not just imported dependencies. ```cpp // By name and exact revision. auto mod = ctx.getModule("ietf-interfaces", "2018-02-20"); if (mod) std::cout << mod->name() << "\n"; // Only implemented modules (not just imported dependencies). auto implMod = ctx.getModuleImplemented("ietf-interfaces"); if (implMod) std::cout << "implemented: " << implMod->name() << "\n"; // Latest loaded revision regardless of implementation status. auto latestMod = ctx.getModuleLatest("ietf-interfaces"); ``` -------------------------------- ### Attach and Read YANG Metadata with DataNode::newMeta Source: https://context7.com/cesnet/libyang-cpp/llms.txt Attaches metadata (annotations) to a data node and iterates over existing metadata. The module must define the annotation extension. ```cpp auto leaf = ctx.newPath("/example-schema:leafInt32", "42"); // Attach metadata (module must define the annotation extension). leaf.newMeta(annotationModule, "origin", "learned"); // Iterate metadata on a node. for (const auto& m : leaf.meta()) { std::cout << m.name() << " = " << m.valueStr() << " (module: " << m.module().name() << ")" << " internal=" << m.isInternal() << "\n"; } ``` -------------------------------- ### Parse Data Only (Skip Validation) Source: https://context7.com/cesnet/libyang-cpp/llms.txt Parses an instance data document from a string, skipping validation. Supports JSON format. ```cpp auto root3 = ctx.parseData( json, libyang::DataFormat::JSON, libyang::ParseOptions::ParseOnly ); ``` -------------------------------- ### Serialize Data Tree to JSON or XML using printStr Source: https://context7.com/cesnet/libyang-cpp/llms.txt The `printStr` method on a `DataNode` serializes a data tree or a specific node to a string in JSON or XML format. Use `PrintFlags` like `Siblings` to include sibling nodes, `EmptyContainers` to include empty containers, `Shrink` for compact output, and `JsonNoNestedPrefix` to omit module prefixes in JSON. ```cpp auto root = ctx.parseData(json, libyang::DataFormat::JSON); // Pretty-print the whole tree (Siblings includes following siblings). auto out = root->printStr( libyang::DataFormat::JSON, libyang::PrintFlags::Siblings | libyang::PrintFlags::EmptyContainers ); if (out) std::cout << *out; // Compact single-node JSON without nested module prefixes. auto leaf = root->findPath("/example-schema:leafInt8"); auto compact = leaf->printStr( libyang::DataFormat::JSON, libyang::PrintFlags::Shrink | libyang::PrintFlags::JsonNoNestedPrefix ); // compact == R"({\"example-schema:leafInt8\":-43})" // Serialize as XML. auto xml = root->printStr(libyang::DataFormat::XML, libyang::PrintFlags::Siblings); ``` -------------------------------- ### Copy Data Trees Source: https://context7.com/cesnet/libyang-cpp/llms.txt Creates deep copies of DataNodes, optionally including siblings. Use `duplicate` for a single node or `duplicateWithSiblings` for a node and its siblings. Options control recursion and metadata copying. ```cpp auto root = ctx.parseData(json, libyang::DataFormat::JSON); auto leaf = root->findPath("/example-schema:leafInt32"); // Deep copy of a single node. auto copy = leaf->duplicate(libyang::DuplicationOptions::Recursive); std::cout << copy.path() << "\n"; // /example-schema:leafInt32 // Copy a node and all its siblings. auto withSiblings = leaf->duplicateWithSiblings( libyang::DuplicationOptions::Recursive | libyang::DuplicationOptions::NoMeta ); // Print the duplicated subtree. auto str = copy.printStr(libyang::DataFormat::JSON, libyang::PrintFlags::Siblings); ``` -------------------------------- ### Module::printStr Source: https://context7.com/cesnet/libyang-cpp/llms.txt Serializes a loaded and compiled module to a human-readable string in YANG source, compiled YANG, YIN, or tree-diagram format. ```APIDOC ## Module::printStr ### Description Serializes a loaded and compiled module to a human-readable string in YANG source, compiled YANG, YIN, or tree-diagram format. ### Usage ```cpp auto mod = ctx.parseModule(yang, libyang::SchemaFormat::YANG); // ASCII tree diagram. std::string tree = mod.printStr(libyang::SchemaOutputFormat::Tree); std::cout << tree; // module: my-net // +--rw hostname? string // +--rw ipv6-enabled? boolean // YANG source (reformatted). std::string yangOut = mod.printStr(libyang::SchemaOutputFormat::Yang); // Compiled YANG (with resolved groupings, augments, etc.). std::string compiled = mod.printStr(libyang::SchemaOutputFormat::CompiledYang); // YIN (XML encoding of YANG). std::string yin = mod.printStr(libyang::SchemaOutputFormat::Yin); ``` ``` -------------------------------- ### Context::registerModuleCallback Source: https://context7.com/cesnet/libyang-cpp/llms.txt Registers a callback function that libyang invokes when it needs a module that is not currently loaded. The callback can provide the module content or indicate that it cannot supply it. ```APIDOC ## `Context::registerModuleCallback` — supply missing modules dynamically Registers a callback invoked by libyang whenever it needs a module that is not yet loaded. The callback returns the module content or `std::nullopt` to indicate it cannot provide it. ```cpp ctx.registerModuleCallback( [](const std::string& modName, const std::optional& /*revision*/, const std::optional& /*submodName*/, const std::optional& /*submodRev*/) -> std::optional { if (modName == "my-module") { return libyang::ModuleInfo{ .data = my_yang_string, // std::string with YANG text .format = libyang::SchemaFormat::YANG }; } return std::nullopt; // cannot supply this module } ); // Now loading "my-module" will trigger the callback. auto mod = ctx.loadModule("my-module"); ``` ``` -------------------------------- ### Find Schema Nodes by XPath Source: https://context7.com/cesnet/libyang-cpp/llms.txt Locates schema nodes using an XPath expression. Returns a `Set` which may contain multiple matching nodes. ```cpp // XPath can return multiple results. auto set = ctx.findXPath("/type_module:listAdvancedWithTwoKey"); for (const auto& node : set) { std::cout << node.path() << "\n"; } ``` -------------------------------- ### Context::findPath / Context::findXPath Source: https://context7.com/cesnet/libyang-cpp/llms.txt Locates schema nodes using either an exact data path or an XPath expression. `findPath` returns a single `SchemaNode` or throws an error if not found, while `findXPath` returns a set of matching `SchemaNode`s. ```APIDOC ## `Context::findPath` / `Context::findXPath` — find schema nodes by path Locates a compiled schema node by its exact data path, or returns a `Set` for an XPath expression (which may match multiple nodes). ```cpp // Exact path lookup — throws libyang::Error if not found. auto schemaLeaf = ctx.findPath("/example-schema:leafInt8"); std::cout << schemaLeaf.name() << "\n"; // leafInt8 std::cout << schemaLeaf.path() << "\n"; // /example-schema:leafInt8 std::cout << (int)schemaLeaf.nodeType() << "\n"; // NodeType::Leaf // RPC output nodes require the Output flag. auto outputNode = ctx.findPath( "/example-schema:myRpc/outputLeaf", libyang::InputOutputNodes::Output ); // XPath can return multiple results. auto set = ctx.findXPath("/type_module:listAdvancedWithTwoKey"); for (const auto& node : set) { std::cout << node.path() << "\n"; } ``` ```