libyang接口使用
HappyOJ  post at 8 months ago 39.9k 0 0

libyang学习:主要是为了学习如何将yang模型data path 转化为schema path。

背景:最近在做一个yang的gtest配置下发测试工具时,遇到yang模型xpath带choice case时(参见文章后面的yang模型):
data path不带choice case节点,如:/acme-system:system/food/tea
schema path是带的,如:/acme-system:system/food/snack/late-bight/tea
导致业务基于schema path注册回调函数时,基于data path数据注入时找不到回调函数,所以需要做一次转换,以便能够给予path找到回调函数。

思路:从data path获取 lysc_node,再从 lysc_node 获取schema path。

  1. LY_ERR ret = LY_SUCCESS;
  2. struct ly_ctx *ctx = NULL;
  3. const struct lys_module *module;
  4. // 初始化libyang上下文
  5. ret = ly_ctx_new("/home/jungle/code/libyang/tests/modules/yang", 0, &ctx);
  6. if (!ctx) {
  7. fprintf(stderr, "Failed to create context.\n");
  8. return 1;
  9. }
  10. // 加载YANG模块
  11. // 假设YANG模块文件名为 "acme-system.yang"
  12. module = ly_ctx_load_module(ctx, "acme-system", NULL, NULL);
  13. if (!module) {
  14. fprintf(stderr, "Failed to load module.\n");
  15. ly_ctx_destroy(ctx);
  16. return 1;
  17. }
  18. // 打印整个yang模型
  19. char *str = NULL;
  20. lys_print_mem(&str, module, LYS_OUT_TREE, 0);
  21. printf("\r\nyang module:\r\n%s\r\n", str);
  22. free(str);
  23. /* using lysc tree */
  24. ly_ctx_set_options(ctx, LY_CTX_SET_PRIV_PARSED);
  25. // 初始化输出
  26. char *printed;
  27. struct ly_out *out;
  28. ly_out_new_memory(&printed, 0, &out);
  29. // 从data path获取 lysc_node
  30. const struct lysc_node *node_lysc = lys_find_path(ctx, NULL, "/acme-system:system/food/tea", 0);
  31. lys_print_node(out, node_lysc, LYS_OUT_TREE, 0, LYS_PRINT_NO_SUBSTMT);
  32. int len = ly_out_printed(out);
  33. printf("\r\nlys_find_path:\r\n%s\r\n", printed);
  34. // 根据lysc_node 转 schema path
  35. char path[4078] = {0};
  36. lysc_path(node_lysc, LYSC_PATH_LOG, path, 4078);
  37. printf("\r\nschema path=%s\r\n", path);
  38. // 从schema path获取 lysc_node
  39. node_lysc = find_schema_path(ctx, "/acme-system:system/food/snack/late-bight/tea");
  40. if (node_lysc) {
  41. lys_print_node(out, node_lysc, LYS_OUT_TREE, 0, LYS_PRINT_NO_SUBSTMT);
  42. int len = ly_out_printed(out);
  43. printf("\r\nfind_schema_path:\r\n%s\r\n", printed);
  44. }
  45. ly_out_reset(out);
  46. // 创建树
  47. struct lyd_node *data = NULL;
  48. //lyd_new_path(NULL, ctx, "/acme-system:system/host-name", "huawei", 0, &data);
  49. lyd_new_path(NULL, ctx, "/acme-system:system/food/tea", "longjungcha", 0, &data);
  50. LY_ERR _r = lyd_print_mem(&str, data, LYD_JSON, LYS_PRINT_SHRINK);
  51. printf("\r\nLYD_JSON:\r\n%s\r\n", str);
  52. free(str);
  53. // 打印data path
  54. char *path_ = lyd_path(data, LYD_PATH_STD, NULL, 0);
  55. printf("\r\nLYD_PATH_STD:\r\n%s\r\n", path_);
  56. free(path_);
  57. lyd_free_siblings(data);
  58. ly_ctx_destroy(ctx);

运行结果如下:

  1. yang module:
  2. module: acme-system
  3. +--rw system
  4. +--rw host-name? string
  5. +--rw domain-search* string
  6. +--rw login
  7. | +--rw message? string
  8. | +--rw user* [name]
  9. | +--rw name string
  10. +--rw food
  11. +--rw (snack)?
  12. +--:(sport-arena)
  13. | +--rw pretzel? string
  14. +--:(late-bight)
  15. +--rw tea? string
  16. lys_find_path:
  17. module: acme-system
  18. +--rw system
  19. +--rw food
  20. +--rw (snack)?
  21. +--:(late-bight)
  22. +--rw tea? string
  23. schema path=/acme-system:system/food/snack/late-bight/tea
  24. find_schema_path:
  25. module: acme-system
  26. +--rw system
  27. +--rw food
  28. +--rw (snack)?
  29. +--:(late-bight)
  30. +--rw tea? string
  31. module: acme-system
  32. +--rw system
  33. +--rw food
  34. +--rw (snack)?
  35. +--:(late-bight)
  36. +--rw tea? string
  37. LYD_JSON:
  38. {"acme-system:system":{"food":{"tea":"longjungcha"}}}
  39. LYD_PATH_STD:
  40. /acme-system:system

最后附上yang模型:

  1. module acme-system {
  2. namespace "http://acme.example.com/system";
  3. prefix "acme";
  4. organization "ACME Inc.";
  5. contact "joe@acme.example.com";
  6. description
  7. "The module for entities implementing the ACME system.";
  8. revision 2007-06-09 {
  9. description "Initial revision.";
  10. }
  11. container system {
  12. leaf host-name {
  13. type string;
  14. description "Hostname for this system";
  15. }
  16. leaf-list domain-search {
  17. type string;
  18. description "List of domain names to search";
  19. }
  20. container login {
  21. leaf message {
  22. type string;
  23. description
  24. "Message given at start of login session";
  25. }
  26. list user {
  27. key "name";
  28. leaf name {
  29. type string;
  30. }
  31. }
  32. }
  33. container food {
  34. choice snack {
  35. case sport-arena {
  36. leaf pretzel {
  37. type string;
  38. }
  39. }
  40. case late-bight {
  41. leaf tea {
  42. type string;
  43. }
  44. }
  45. }
  46. }
  47. }
  48. }