libyang icon indicating copy to clipboard operation
libyang copied to clipboard

how to get the rest of the content from its `tree` member.

Open ipseokri opened this issue 1 year ago • 2 comments

          > Once you get the `data` node, you need to cast it to `lyd_node_any` and then get the rest of the content from its `tree` member.

Hello, I'm a student who is studying yang & neconf.

I'm trying to extract my list data from the data node with the command,

I'm trying to get rid of node for for loop and get list data.

but continuously failed.

struct nc_rpc* rt_rpc = nc_rpc_getconfig(NC_DATASTORE_RUNNING, filter, NC_WD_UNKNOWN, NC_PARAMTYPE_CONST);


ret = nc_send_rpc(session, rt_rpc, 1000, &msgid);
if (ret != NC_MSG_RPC) {
    fprintf(stderr, "Failed to send get-config RPC\n");
    nc_rpc_free(rt_rpc);
}
msgtype = nc_recv_reply(session, rt_rpc, msgid, 10000, &envp, &op);
if (msgtype != NC_MSG_REPLY) {
    fprintf(stderr, "Failed to receive get-config reply\n");
    nc_rpc_free(rt_rpc);
}

lyd_print_file(stdout, op, LYD_XML, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS);
printf("\n");

struct lyd_node_any *any_node = (struct lyd_node_any *)op;
struct lyd_node *actual_data = any_node->value.tree;

fillSwitchInfo(actual_data, &switchInfo);

I'm trying to get data with lyd_node_any and using raw op variable both.

but both failed. there is no child after node.

`void fillSwitchInfo(struct lyd_node *node, SwitchInfo *switchInfo) { LY_ERR err; struct lyd_node *next; struct lyd_node_inner *inner; printf("fillSwitchInfo\n");

LYD_TREE_DFS_BEGIN(node, next) {
    printf("string : %s\n", next->schema->name);
    if (!strcmp(next->schema->name, "dpid")) {
        switchInfo->dpid = MAC_to_uint64(lyd_get_value(next));
        printf("dpid : %d \n", switchInfo->dpid);
    } else if (!strcmp(next->schema->name, "port")) {
        inner = (struct lyd_node_inner *)next;
        fillPortStatuses(inner, switchInfo->port_statuses);
    } else if (!strcmp(next->schema->name, "table_entry")) {
        inner = (struct lyd_node_inner *)next;
        //fillTableEntries(inner, switchInfo->l2_table_entries, switchInfo->cbs_table_entries);
    }
    LYD_TREE_DFS_END(node, next);
}

}

`

this is my fillswitchinfo function, but not working.

the data from command looks like this one. but there is no child after node.

<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><switch_info xmlns="urn:lgessu:params:xml:ns:yang:SmStubStd"><dpid>00:1d:7e:8a:74:d7</dpid><port_status><port><port_number>1</port_number><status>ALIVE</status></port><port><port_number>2</port_number><status>SLEEP</status></port></port_status><l2_table><table_entry><key>101</key><MAC_address>00:1d:7e:8a:74:d8</MAC_address><output_port>2</output_port></table_entry><table_entry><key>102</key><MAC_address>00:1d:7e:8a:74:d9</MAC_address><output_port>3</output_port></table_entry></l2_table><cbs_table><table_entry><key>201</key><bandwidth>100</bandwidth></table_entry><table_entry><key>202</key><bandwidth>150</bandwidth></table_entry></cbs_table></switch_info></data>

what should I do for extract data from get-config raw data.

Originally posted by @ipseokri in https://github.com/CESNET/libyang/issues/1890#issuecomment-2118240194

ipseokri avatar May 18 '24 01:05 ipseokri

If you're looking for some examples and if you can read C++ code, you can look at how this is done in the C++ bindings. We do not wrap <get-config>, but there's code for NETCONF's <get> and NMDA's <get-data>. The code essentially:

  • calls n_recv_reply
  • checks for errors from the NETCONF envelope, as parsed by libnetconf2
  • calls lyd_find_path to discover the correct node to work on
  • casts the result to an appropriate type because it's actually anydata or anyxml and not a regular child

jktjkt avatar May 19 '24 19:05 jktjkt

You can try what @jktjkt said and my sentence you quoted should explain what to do. You can use lyd_find_path() to get the node.

struct lyd_node *node, *child;
struct lyd_node_any *any;

lyd_find_path(op, "/ietf-netconf:get-config/data", 1, &node);
any = (struct lyd_node_any *)node;
child = any->value.tree;

child is the child you could not find.

michalvasko avatar May 20 '24 07:05 michalvasko