modelschemaietf-netmod-yangyang

YANG and Choice - what does the XML look like?


I am trying to figure out the proper syntax for implementing the choice field from a yang model into its corresponding configuration xml. Unfortunately, the documentation in RFC 6020 and other Yang related web pages don't seem to show how to use a choice field in the actual XML which speaks to the Yang model.

For example, here is my YANG model:

container MYMODEL {
    container PacketOperationConf {
        list RuleID {
            key id;
            leaf id {
                type int32;
            }
            leaf priority { 
                type int32; 
            }
            leaf name { 
                type string; 
            }
            choice type {
                case flow {
                    list action {
                        key order;
                        uses mymodel:action;
                    }
                    container match {
                        uses mymodel:match;
                    }
                }
                case function {
                    container function {
                        
                    }
                }
            }
        }
        ...

And there is the corresponding XML for this container:

<?xml version="1.0" encoding="UTF-8" ?>
<rpc message-id="101"
    xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <edit-config>
        <target>
            <running />
        </target>
        <config>
            <MYMODEL xmlns="urn:com:tug:mymodel">
                <PacketOperationConf>
                    <RuleID>
                        <id>101</id>
                        <type>
                            <flow>
                                <action>
                                    <order>1</order>
                                    <set-dl-src-action>
                                        <address>01:02:03:04:05:06</address>
                                    </set-dl-src-action>
                                </action>
                            </flow>
                        </type>
                    </RuleID>
                </PacketOperationConf>
            </MYMODEL>
        </config>
    </edit-config>
</rpc>

But when I run this through yang2dsdl I get the following error:

$ yang2dsdl -t edit-config -v rmbn-full-test-1.xml -d /tmp rmbn-full.yang
== Generating RELAX NG schema '/tmp/rmbn-full-edit-config.rng'
Done.

== Validating grammar and datatypes ...
rmbn-full-test-1.xml:13: element type: Relax-NG validity error : Element RuleID has extra content: type
Relax-NG validity error : Extra element RuleID in interleave
rmbn-full-test-1.xml:11: element RuleID: Relax-NG validity error : Element PacketOperationConf failed to validate content
rmbn-full-test-1.xml fails to validate

So the error happens because it doesn't know what to do with the type element. The type element is the name of my choice section in the yang model.

I have tried a variety of arrangements of this, however none have worked. I'm also unable to find anything on SOF or Google on examples of choices as implemented in XML.


Solution

  • Both case and choice are what the RFC refers to as schema nodes, but they are not also data nodes - schema nodes that may be instantiated. Therefore choice and case nodes never appear in a valid instance document, they only impose restrictions on what a valid instance document is.

    In your case, that would mean an optional choice (XOR) between:

    To put it another way, if <action> appears in the instance document, <match> may also appear (and vice versa), but <function> may not appear.

    Here's a valid document (did not actually test).

    <?xml version="1.0" encoding="UTF-8" ?>
    <rpc message-id="101"
        xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
        <edit-config>
            <target>
                <running />
            </target>
            <config>
                <RMBN xmlns="urn:com:tug:rmbn-full">
                    <PacketOperationConf>
                        <RuleID>
                            <id>101</id>
                            <action>
                                <order>1</order>
                                <set-dl-src-action>
                                    <address>01:02:03:04:05:06</address>
                                </set-dl-src-action>
                            </action>
                        </RuleID>
                    </PacketOperationConf>
                </RMBN>
            </config>
        </edit-config>
    </rpc>
    

    Below is some text from RFC6020 (YANG version 1.0), since you specifically asked about that version (Section 7.9).

    The "choice" statement defines a set of alternatives, only one of which may exist at any one time. The argument is an identifier, followed by a block of substatements that holds detailed choice information. The identifier is used to identify the choice node in the schema tree. A choice node does not exist in the data tree.

    A choice consists of a number of branches, defined with the "case" substatement. Each branch contains a number of child nodes. The nodes from at most one of the choice's branches exist at the same time.

    The "case" statement is used to define branches of the choice. It takes as an argument an identifier, followed by a block of substatements that holds detailed case information.

    The identifier is used to identify the case node in the schema tree. A case node does not exist in the data tree.

    Within a "case" statement, the "anyxml", "choice", "container", "leaf", "list", "leaf-list", and "uses" statements can be used to define child nodes to the case node. The identifiers of all these child nodes MUST be unique within all cases in a choice.