7.17. “扩充”声明

augment”语句允许模块或子模块添加到在外部模块或当前模块及其子模块中定义的模式树中,并通过“uses”语句中的分组添加到节点中。 参数是标识架构树中节点的字符串。 这个节点被称为增广的目标节点。 目标节点必须是containerlistchoicecaseinputoutputnotification节点。 随着“augment”语句之后的子语句中定义的节点的增加。

参数字符串是一个模式节点标识符(参见第6.5节)。如果“augment”语句位于模块或子模块的顶层,必须使用模式节点标识符的绝对格式(由第14节中的规则“absolute-schema-nodeid”定义)。如果“augment”语句是“uses”语句的子语句,则必须使用后代形式(由第14节中的规则“descendant-schema-nodeid”定义)。

如果目标节点是容器,列表,case,输入,输出或通知节点,则“container”,“leaf”,“list”,“leaf-list”,“uses”和“choice”语句可以是在“augment”声明中使用。

如果目标节点是容器或列表节点,则可以在“augment”语句中使用“Operation”和“notification”语句。

如果目标节点是一个choice节点,则可以在“augment”语句中使用“case”语句或简写“case”语句(参见第7.9.2节)。

augment”语句绝不能将同一个模块中具有相同名称的多个节点添加到目标节点。

如果增加在另一个模块中添加了表示配置到目标节点的强制节点(参见第3节),则必须使用“when”语句使该扩充有条件。定义“when”表达式时必须小心,以避免不知道扩充模块的客户端中断。

在下面的例子中,用“mandatory-leaf”扩充“interface”条目是可以的,因为增加依赖于对“some-new-iftype”的支持。旧客户端不知道这种类型,所以它不会选择这种类型,因此不会添加强制数据节点。

  1. module example-augment {
  2. yang-version 1.1;
  3. namespace "urn:example:augment";
  4. prefix mymod;
  5. import ietf-interfaces {
  6. prefix if;
  7. }
  8. identity some-new-iftype {
  9. base if:interface-type;
  10. }
  11. augment "/if:interfaces/if:interface" {
  12. when 'derived-from-or-self(if:type, "mymod:some-new-iftype")';
  13. leaf mandatory-leaf {
  14. mandatory true;
  15. type string;
  16. }
  17. }
  18. }

7.17.1. augment子语句

  1. +--------------+---------+-------------+
  2. | substatement | section | cardinality |
  3. +--------------+---------+-------------+
  4. | action | 7.15 | 0..n |
  5. | anydata | 7.10 | 0..n |
  6. | anyxml | 7.11 | 0..n |
  7. | case | 7.9.2 | 0..n |
  8. | choice | 7.9 | 0..n |
  9. | container | 7.5 | 0..n |
  10. | description | 7.21.3 | 0..1 |
  11. | if-feature | 7.20.2 | 0..n |
  12. | leaf | 7.6 | 0..n |
  13. | leaf-list | 7.7 | 0..n |
  14. | list | 7.8 | 0..n |
  15. | notification | 7.16 | 0..n |
  16. | reference | 7.21.4 | 0..1 |
  17. | status | 7.21.2 | 0..1 |
  18. | uses | 7.13 | 0..n |
  19. | when | 7.21.5 | 0..1 |
  20. +--------------+---------+-------------+

7.17.2. XML编码规则

在“augment”语句中定义的所有数据节点都被定义为指定“augment”的模块的XML名称空间中的XML元素。

当一个节点被扩充时,扩充子节点以任何顺序被编码为扩充节点的子元素。

7.17.3. 使用示例

在命名空间urn:example:interface-module,我们有:

  1. container interfaces {
  2. list ifEntry {
  3. key "ifIndex";
  4. leaf ifIndex {
  5. type uint32;
  6. }
  7. leaf ifDescr {
  8. type string;
  9. }
  10. leaf ifType {
  11. type iana:IfType;
  12. }
  13. leaf ifMtu {
  14. type int32;
  15. }
  16. }
  17. }

然后,在命名空间urn:example:ds0,我们有:

  1. import example-interface-module {
  2. prefix "if";
  3. }
  4. augment "/if:interfaces/if:ifEntry" {
  5. when "if:ifType='ds0'";
  6. leaf ds0ChannelNumber {
  7. type ChannelNumber;
  8. }
  9. }

相应的XML实例示例:

  1. <interfaces xmlns="urn:example:interface-module"
  2. xmlns:ds0="urn:example:ds0">
  3. <ifEntry>
  4. <ifIndex>1</ifIndex>
  5. <ifDescr>Flintstone Inc Ethernet A562</ifDescr>
  6. <ifType>ethernetCsmacd</ifType>
  7. <ifMtu>1500</ifMtu>
  8. </ifEntry>
  9. <ifEntry>
  10. <ifIndex>2</ifIndex>
  11. <ifDescr>Flintstone Inc DS0</ifDescr>
  12. <ifType>ds0</ifType>
  13. <ds0:ds0ChannelNumber>1</ds0:ds0ChannelNumber>
  14. </ifEntry>
  15. </interfaces>

作为另一个例子,假设我们有7.9.6节定义的选择。 以下构造可用于扩展协议定义:

  1. augment /ex:system/ex:protocol/ex:name {
  2. case c {
  3. leaf smtp {
  4. type empty;
  5. }
  6. }
  7. }

相应的XML实例示例:

  1. <ex:system>
  2. <ex:protocol>
  3. <ex:tcp/>
  4. </ex:protocol>
  5. </ex:system>

  1. <ex:system>
  2. <ex:protocol>
  3. <other:smtp/>
  4. </ex:protocol>
  5. </ex:system>