为什么pyang在这种情况下不会抛出错误

时间:2017-03-06 16:36:27

标签: ietf-netmod-yang

当条件指的是不存在的节点时,

以下内容。我想知道为什么pyang不会抛出错误?如果我使用错误的前缀,它确实如此。

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

是否允许(在表达式时)从扩充本身引用模式?

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;
          }
       }
    } 
}

1 个答案:

答案 0 :(得分: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)。

是的,您可以参考以上&#34;以上的节点&#34;扩充的目标节点或者是它的兄弟姐妹 - 实际上,你总是应该在when语句正在运行时(它不应该引用由它构成条件的任何节点)。

此外,你永远不应该试图打破&#34;模块限制&#34;使用非前缀节点测试(例如b3b1)。 XPath表达式只能看到在定义模块和定义模块本身的导入中定义的名称。例如,即使b3稍后被某个未知的第三个模块增强,您的条件仍将评估为false。最好假设非前缀名称属于定义模块的命名空间。