7.9. “选择”声明

choice”语句定义了一组替代品,其中只有一个可能出现在任何一个数据树中。 参数是一个标识符,后面跟着一个包含详细选择信息的子状态块。 该标识符用于标识架构树中的选择节点。 数据树中不存在选择节点。

一个选择由若干分支组成,每个分支都定义一个“case”子语句。 每个分支都包含一些子节点。 选择分支中的至多一个节点同时存在。

由于在数据树中,只有一个选择的情况在任何时候都是有效的,所以从一种情况创建一个节点会隐式地删除所有其他情况下的所有节点。 如果一个请求从一个案例中创建一个节点,服务器将删除在其他情况下定义的所有现有节点。

7.9.1. choice的子语句

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

7.9.2. 选择的”case“声明

case”语句用于定义选择的分支。 它将一个标识符作为参数,后面跟着一个包含详细案例信息的子状态块。

标识符用于标识架构树中的case节点。 数据树中不存在case节点。

在“case”语句中,可以使用“anydata”,“anyxml”,“choice”,“container”,“leaf”,“list”,“leaf-list”和“uses”语句来定义子节点到case节点。 在选择的所有情况下,所有这些子节点的标识符必须是唯一的。 例如,以下是非法的:

  1. choice interface-type { // 这个例子是非法的YANG
  2. case a {
  3. leaf ethernet { ... }
  4. }
  5. case b {
  6. container ethernet { ...}
  7. }
  8. }

作为简写,如果分支包含单个“anydata”,“anyxml”,“choice”,“container”,“leaf”,“list”或“leaf-list”语句,则可以省略“case”语句。 在这种情况下,case节点仍然存在于模式树中,其标识符与子节点的标识符相同。 模式节点标识符(6.5节)必须总是明确地包含节点标识符。 下面的例子:

  1. choice interface-type {
  2. container ethernet { ... }
  3. }

相当于:

  1. choice interface-type {
  2. case ethernet {
  3. container ethernet { ... }
  4. }
  5. }

case标识符在选择中必须是唯一的。

7.9.2.1. case的子语句

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

7.9.3. 选择的“default”声明

如果没有来自任何选择情况的子节点存在,则“default”语句指示是否应将情况视为默认情况。参数是默认的“case”语句的标识符。如果“default”语句丢失,则没有默认情况。

default”语句不能出现在“mandatory”为“true”的选项上。

默认情况下,仅在考虑情况下的节点的“default”语句(即,叶子和叶列表的默认值以及嵌套选择的默认情况)时才是重要的。如果任何情况下的节点都不存在,则使用缺省情况下的默认值和嵌套的默认情况。

在默认情况下,不能有任何强制节点(第3节)。

case下的子节点的缺省值只有在该案例下的其中一个节点存在或者case是默认情况下才会使用。如果case中没有任何节点存在,并且case不是默认情况,则忽略case的子节点的默认值。

在本例中,选项默认为“interval”,如果没有“daily”,“time-of-day”或“manual”,则使用默认值。 如果“daily”存在,将使用“time-of-day”的默认值。

  1. container transfer {
  2. choice how {
  3. default interval;
  4. case interval {
  5. leaf interval {
  6. type uint16;
  7. units minutes;
  8. default 30;
  9. }
  10. }
  11. case daily {
  12. leaf daily {
  13. type empty;
  14. }
  15. leaf time-of-day {
  16. type string;
  17. units 24-hour-clock;
  18. default "01.00";
  19. }
  20. }
  21. case manual {
  22. leaf manual {
  23. type empty;
  24. }
  25. }
  26. }
  27. }

7.9.4. 选择的“mandatory”声明

mandatory”语句是可选的,它将字符串“true”或“false”作为参数,并对有效数据进行约束。 如果“mandatory”是“true”,则必须至少有一个选择的案例分支中的一个节点存在。

如果未指定,则默认为“false”。

约束的行为取决于模式树中不是不存在容器的选择最接近的祖先节点的类型(请参阅第7.5.1节):

  • 如果模式树中不存在这样的祖先,则强制约束。

  • 否则,如果这个祖先是一个case节点,那么如果这个case的任何其他节点存在,这个约束就会被执行。

  • 否则,如果祖先节点存在,则强制执行。

根据第8节的规定,约束条件得到了进一步的执行。

7.9.5. XML编码规则

选择和案例节点在XML中不可见。

所选“case”语句的子节点必须按照它们在“case”语句中定义的顺序编码,如果它们是RPC或动作输入(action input)或输出参数(output parameter)定义的一部分。 否则,子元素按任何顺序编码。

7.9.6. 使用示例

给出以下选择:

  1. container protocol {
  2. choice name {
  3. case a {
  4. leaf udp {
  5. type empty;
  6. }
  7. }
  8. case b {
  9. leaf tcp {
  10. type empty;
  11. }
  12. }
  13. }
  14. }

相应的XML实例示例:

  1. <protocol>
  2. <tcp/>
  3. </protocol>

将协议从TCP更改为UDP

  1. <rpc message-id="101"
  2. xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
  3. xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
  4. <edit-config>
  5. <target>
  6. <running/>
  7. </target>
  8. <config>
  9. <system xmlns="urn:example:config">
  10. <protocol>
  11. <udp nc:operation="create"/>
  12. </protocol>
  13. </system>
  14. </config>
  15. </edit-config>
  16. </rpc>