1

以下 when 条件指的是不存在的节点。我想知道为什么 pyang 不抛出错误?确实,如果我使用了错误的前缀。

请您查看何时条件(嵌入在模块中)。

是否允许(在 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;
          }
       }
    } 
}
4

1 回答 1

1

这是因为 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永远存在)。

是的,您可以引用增强的目标节点“上方”或其兄弟节点的节点 - 事实上,当when语句正在播放时,您总是应该引用(它不应该引用任何由它作为条件的节点)。

此外,您永远不应该尝试使用不带前缀的节点测试(例如b3and b1)来打破“模块限制”。XPath 表达式只能看到在定义模块和定义模块本身的导入中定义的名称。例如,即使b3后来被某个未知的第三个模块增强,您的条件仍会评估为false. 最好假设无前缀名称属于定义模块的命名空间。

于 2017-03-07T09:01:53.817 回答