为什么pyang在这种情况下不会抛出错误
why pyang does not throw error in this scenario
以下条件指的是不存在的节点。我想知道为什么 pyang 不抛出错误?确实如此,如果我使用了错误的前缀。
请您查看 when 条件(嵌入在模块中)。
是否允许(在 when 表达式中)从扩充本身引用模式?
module mod-w-1 {
namespace "http://example.org/tests/mod-w-1";
prefix m1;
container m1 {
leaf b1 {
type string;
}
}
}
module when-tests {
namespace "http://example.org/tests/when-tests";
prefix wt;
import mod-w-1 {
prefix m1;
}
augment "/m1:m1" {
// when "/m1:m1/b3 = 'abc'";
// there is no b3, so, should be invalid.
// when "/m1:m1/b1 = 'abc'";
// a payload or data situation that has m1/b1 != 'abc' will cause the
// data that fits this augment content will be invalid/rejected.
/* for ex;
<m1>
<b1>fff</b1>
<x>sfsf</x>
<conditional>
<foo>dddd</foo>
</conditional>
</m1>
is invalid, hence, the <x> and <conditional> parts will be
rejected.
*/
leaf x {
type string;
}
container conditional {
leaf foo {
type string;
}
}
}
}
这是因为 pyang 根本不验证 XPath 表达式的语义,只验证它们的语法 - 以及一些额外的检查,例如函数和前缀的使用。您将需要另一个 YANG 编译器来正确验证它们。
def v_xpath(ctx, stmt):
try:
toks = xpath.tokens(stmt.arg)
for (tokname, s) in toks:
if tokname == 'name' or tokname == 'prefix-match':
i = s.find(':')
if i != -1:
prefix = s[:i]
prefix_to_module(stmt.i_module, prefix, stmt.pos,
ctx.errors)
elif tokname == 'literal':
# kind of hack to detect qnames, and mark the prefixes
# as being used in order to avoid warnings.
if s[0] == s[-1] and s[0] in ("'", '"'):
s = s[1:-1]
i = s.find(':')
# make sure there is just one : present
if i != -1 and s[i+1:].find(':') == -1:
prefix = s[:i]
# we don't want to report an error; just mark the
# prefix as being used.
my_errors = []
prefix_to_module(stmt.i_module, prefix, stmt.pos,
my_errors)
for (pos, code, arg) in my_errors:
if code == 'PREFIX_NOT_DEFINED':
err_add(ctx.errors, pos,
'WPREFIX_NOT_DEFINED', arg)
elif ctx.lax_xpath_checks == True:
pass
elif tokname == 'variable':
err_add(ctx.errors, stmt.pos, 'XPATH_VARIABLE', s)
elif tokname == 'function':
if not (s in xpath.core_functions or
s in yang_xpath_functions or
(stmt.i_module.i_version != '1' and
s in yang_1_1_xpath_functions) or
s in extra_xpath_functions):
err_add(ctx.errors, stmt.pos, 'XPATH_FUNCTION', s)
except SyntaxError as e:
err_add(ctx.errors, stmt.pos, 'XPATH_SYNTAX_ERROR', e)
statements.py 的 1993 行。
请注意,从 XPath 规范的角度来看,引用不存在节点的 XPath 表达式在技术上并非无效。这只是意味着位置路径将选择一个空节点集(并且您的条件将永远是false
)。
是的,您可以引用 "above" 扩充的目标节点或其兄弟节点 - 事实上,当 when
语句正在运行时,您总是应该引用(它不应该引用任何有条件的节点)。
此外,您永远不应尝试使用非前缀节点测试(例如 b3
和 b1
)来破坏 "module confinement"。 XPath 表达式只能看到在定义模块和定义模块本身的导入中定义的名称。例如,即使 b3
后来被某个未知的第三个模块扩充,您的条件仍然会评估为 false
。最好假定非前缀名称属于定义模块的命名空间。
以下条件指的是不存在的节点。我想知道为什么 pyang 不抛出错误?确实如此,如果我使用了错误的前缀。
请您查看 when 条件(嵌入在模块中)。
是否允许(在 when 表达式中)从扩充本身引用模式?
module mod-w-1 {
namespace "http://example.org/tests/mod-w-1";
prefix m1;
container m1 {
leaf b1 {
type string;
}
}
}
module when-tests {
namespace "http://example.org/tests/when-tests";
prefix wt;
import mod-w-1 {
prefix m1;
}
augment "/m1:m1" {
// when "/m1:m1/b3 = 'abc'";
// there is no b3, so, should be invalid.
// when "/m1:m1/b1 = 'abc'";
// a payload or data situation that has m1/b1 != 'abc' will cause the
// data that fits this augment content will be invalid/rejected.
/* for ex;
<m1>
<b1>fff</b1>
<x>sfsf</x>
<conditional>
<foo>dddd</foo>
</conditional>
</m1>
is invalid, hence, the <x> and <conditional> parts will be
rejected.
*/
leaf x {
type string;
}
container conditional {
leaf foo {
type string;
}
}
}
}
这是因为 pyang 根本不验证 XPath 表达式的语义,只验证它们的语法 - 以及一些额外的检查,例如函数和前缀的使用。您将需要另一个 YANG 编译器来正确验证它们。
def v_xpath(ctx, stmt):
try:
toks = xpath.tokens(stmt.arg)
for (tokname, s) in toks:
if tokname == 'name' or tokname == 'prefix-match':
i = s.find(':')
if i != -1:
prefix = s[:i]
prefix_to_module(stmt.i_module, prefix, stmt.pos,
ctx.errors)
elif tokname == 'literal':
# kind of hack to detect qnames, and mark the prefixes
# as being used in order to avoid warnings.
if s[0] == s[-1] and s[0] in ("'", '"'):
s = s[1:-1]
i = s.find(':')
# make sure there is just one : present
if i != -1 and s[i+1:].find(':') == -1:
prefix = s[:i]
# we don't want to report an error; just mark the
# prefix as being used.
my_errors = []
prefix_to_module(stmt.i_module, prefix, stmt.pos,
my_errors)
for (pos, code, arg) in my_errors:
if code == 'PREFIX_NOT_DEFINED':
err_add(ctx.errors, pos,
'WPREFIX_NOT_DEFINED', arg)
elif ctx.lax_xpath_checks == True:
pass
elif tokname == 'variable':
err_add(ctx.errors, stmt.pos, 'XPATH_VARIABLE', s)
elif tokname == 'function':
if not (s in xpath.core_functions or
s in yang_xpath_functions or
(stmt.i_module.i_version != '1' and
s in yang_1_1_xpath_functions) or
s in extra_xpath_functions):
err_add(ctx.errors, stmt.pos, 'XPATH_FUNCTION', s)
except SyntaxError as e:
err_add(ctx.errors, stmt.pos, 'XPATH_SYNTAX_ERROR', e)
statements.py 的 1993 行。
请注意,从 XPath 规范的角度来看,引用不存在节点的 XPath 表达式在技术上并非无效。这只是意味着位置路径将选择一个空节点集(并且您的条件将永远是false
)。
是的,您可以引用 "above" 扩充的目标节点或其兄弟节点 - 事实上,当 when
语句正在运行时,您总是应该引用(它不应该引用任何有条件的节点)。
此外,您永远不应尝试使用非前缀节点测试(例如 b3
和 b1
)来破坏 "module confinement"。 XPath 表达式只能看到在定义模块和定义模块本身的导入中定义的名称。例如,即使 b3
后来被某个未知的第三个模块扩充,您的条件仍然会评估为 false
。最好假定非前缀名称属于定义模块的命名空间。