Skip to content

Commit 5be2431

Browse files
committed
context: adds find_xpath_atoms function
This patch is adding find_xpath_atoms on context level to allow users to get all nodes needed for xpath evaluation Signed-off-by: Stefan Gula <[email protected]>
1 parent 3072af0 commit 5be2431

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

cffi/cdefs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ struct lys_module* ly_ctx_get_module_latest(const struct ly_ctx *, const char *)
215215
LY_ERR ly_ctx_compile(struct ly_ctx *);
216216

217217
LY_ERR lys_find_xpath(const struct ly_ctx *, const struct lysc_node *, const char *, uint32_t, struct ly_set **);
218+
LY_ERR lys_find_xpath_atoms(const struct ly_ctx *, const struct lysc_node *, const char *, uint32_t, struct ly_set **);
218219
void ly_set_free(struct ly_set *, void(*)(void *obj));
219220

220221
struct ly_set {

libyang/context.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,38 @@ def find_path(
401401
finally:
402402
lib.ly_set_free(node_set, ffi.NULL)
403403

404+
def find_xpath_atoms(
405+
self,
406+
path: str,
407+
output: bool = False,
408+
root_node: Optional["libyang.SNode"] = None,
409+
) -> Iterator[SNode]:
410+
if self.cdata is None:
411+
raise RuntimeError("context already destroyed")
412+
413+
if root_node is not None:
414+
ctx_node = root_node.cdata
415+
else:
416+
ctx_node = ffi.NULL
417+
418+
flags = lib.LYS_FIND_XP_OUTPUT if output else 0
419+
420+
node_set = ffi.new("struct ly_set **")
421+
if (
422+
lib.lys_find_xpath_atoms(self.cdata, ctx_node, str2c(path), flags, node_set)
423+
!= lib.LY_SUCCESS
424+
):
425+
raise self.error("cannot find path")
426+
427+
node_set = node_set[0]
428+
if node_set.count == 0:
429+
raise self.error("cannot find path")
430+
try:
431+
for i in range(node_set.count):
432+
yield SNode.new(self, node_set.snodes[i])
433+
finally:
434+
lib.ly_set_free(node_set, ffi.NULL)
435+
404436
def find_jsonpath(
405437
self,
406438
path: str,

tests/test_context.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import os
55
import unittest
66

7-
from libyang import Context, LibyangError, Module, SLeaf, SLeafList
7+
from libyang import Context, LibyangError, Module, SContainer, SLeaf, SLeafList
88
from libyang.util import c2str
99

1010

@@ -95,6 +95,22 @@ def test_ctx_find_path(self):
9595
node2 = next(ctx.find_path("../number", root_node=node))
9696
self.assertIsInstance(node2, SLeafList)
9797

98+
def test_ctx_find_xpath_atoms(self):
99+
with Context(YANG_DIR) as ctx:
100+
ctx.load_module("yolo-system")
101+
node_iter = ctx.find_xpath_atoms("/yolo-system:conf/offline")
102+
node = next(node_iter)
103+
self.assertIsInstance(node, SContainer)
104+
node = next(node_iter)
105+
self.assertIsInstance(node, SLeaf)
106+
node_iter = ctx.find_xpath_atoms("../number", root_node=node)
107+
node = next(node_iter)
108+
self.assertIsInstance(node, SLeaf)
109+
node = next(node_iter)
110+
self.assertIsInstance(node, SContainer)
111+
node = next(node_iter)
112+
self.assertIsInstance(node, SLeafList)
113+
98114
def test_ctx_iter_modules(self):
99115
with Context(YANG_DIR) as ctx:
100116
ctx.load_module("yolo-system")

0 commit comments

Comments
 (0)