目前我正在与YANG合作,作为(遗留)Python项目的一部分。
我有点坚持定义一个模式的任务,然后用它来验证数据,组织为一个Python字典。 如果有可能,我会"喜欢"保持当前结构,因为很多代码库都在使用这些数据。
"未改变"一条数据:
"namespace": { # Mandatory
"management": { # Optional
"interfaces": { # Mandatory
"m0": { # Optional
"leaf1": "..."
}
}
},
"benchmark": { # Optional
"interfaces": { # Mandatory
"b0": { # Optional
"leaf1": "...",
"leaf2": "..."
},
"b1": { # Optional
"leaf1": "...",
"leaf2": "..."
}
}
}
}
我的问题是所有标记为"可选" (在示例中)将被建模为容器,但似乎根据RFC6020它们不能被定义为可选的(即:强制性假;)。
因此,我定义了一个使用列表的模型。这意味着Python Dict的一些节点(管理,基准,m0,b0,b1)现在是列表元素,无法以当前方式访问,例如:data['namespace']['management']...
修改后的示例如下所示:
"namespace": [
{
"desc": "management",
"interfaces": [
{
"leaf1": "..."
}
]
},
{
"desc": "benchmark",
"interfaces": [
{
"leaf1": "...",
"leaf2": "..."
},
{
"leaf1": "...",
"leaf2": "..."
}
]
}
]
描述(我当前的片段)YANG模型:
list namespace {
description "Namespace definitions.";
key desc;
leaf desc { type string; }
uses leaf-definitions;
list interfaces {
key leaf1;
uses leaf-definitions;
}
}
验证成功并且数据(本身)的转换不是问题,但它导致大量破坏的代码。
这导致了我的问题:
我非常感谢你的意见,因为我对杨很新!
答案 0 :(得分:0)
我是否正确 - 杨的容器总是强制性的吗?
恰恰相反。它们始终是可选的,除非它们包含必需的节点(强制叶,具有min元素> 0的列表或叶列表等)。换句话说,容器从其后代继承此属性。这当然仅适用于不存在的容器。具有强制子项的状态容器不会继承此属性,因为这会破坏其目的(存在)。您可能错过了RFC6020中强制节点的定义:
A mandatory node is one of: o A leaf, choice, or anyxml node with a "mandatory" statement with the value "true". o A list or leaf-list node with a "min-elements" statement with a value greater than zero. o A container node without a "presence" statement, which has at least one mandatory node as a child.
这应该对你的第二个问题有帮助。
是否有其他方法可以模拟这种情况? (不破坏“太多”)
滥用存在容器。它们总是可选的。您也可以通过向非在线容器引入一些必需的子项来避免使用列表。根据您的初始数据:
module mandatory-optional-branch {
namespace "org:example:mandatory-optional-branch";
prefix "mob";
grouping leafs {
leaf leaf1 {type string;}
leaf leaf2 {type string;}
}
list namespace { // mandatory
config false;
min-elements 1;
max-elements 1;
container management { // optional by nature
presence "I have mandatory children, but am not mandatory. Yay for me.
Of course my presence should have some meaning.";
list interfaces { // mandatory
min-elements 1;
max-elements 1;
container m0 { // optional - no mandatory node children
leaf leaf1 {type string;}
}
}
}
container benchmark { // optional by nature
presence "Same as 'management' above.";
list interfaces { // mandatory
min-elements 1;
max-elements 1;
container b0 { // optional - no mandatory node children
uses leafs;
}
container b1 { // optional - no mandatory node children
uses leafs;
}
}
}
}
}