10. Mapping YANG Statements to the Hybrid Schema
Each subsection in this section is devoted to one YANG statement and provides the specification of how the statement is mapped to the hybrid schema. The subsections are sorted alphabetically by the statement keyword. Each YANG statement is mapped to an XML fragment, typically a single element or attribute, but it may also be a larger structure. The mapping procedure is inherently recursive, which means that after finishing a statement the mapping continues with its substatements, if there are any, and a certain element of the resulting fragment becomes the parent of other fragments resulting from the mapping of substatements. Any changes to this default recursive procedure are explicitly specified. YANG XML encoding rules translate to the following rules for ordering multiple subelements: 1. Within the <nma:rpcs> subtree (i.e., for input and output parameters of an RPC operation) the order of subelements is fixed and their definitions in the hybrid schema MUST follow the order specified in the source YANG module. 2. When mapping the 'list' statement, all keys MUST come before any other subelements and in the same order as they are declared in the 'key' statement. The order of the remaining (non-key) subelements is not specified, so their definitions in the hybrid schema MUST be enclosed in the <rng:interleave> element. 3. Otherwise, the order of subelements is arbitrary and, consequently, all definitions of subelements in the hybrid schema MUST be enclosed in the <rng:interleave> element. The following conventions are used in this section: o The argument of the statement being mapped is denoted by ARGUMENT. o The element in the RELAX NG schema that becomes the parent of the resulting XML fragment is denoted by PARENT.10.1. The 'anyxml' Statement
This statement is mapped to the <rng:element> element and ARGUMENT with prepended local namespace prefix becomes the value of its @name attribute. The contents of <rng:element> are: <rng:ref name="__anyxml__"/>
Substatements of the 'anyxml' statement, if any, MAY be mapped to additional children of the <rng:element> element. If at least one 'anyxml' statement occurs in any of the input YANG modules, the following pattern definition MUST be added exactly once to the RELAX NG schema as a child of the root <rng:grammar> element (cf. [Vli04], p. 172): <rng:define name="__anyxml__"> <rng:zeroOrMore> <rng:choice> <rng:attribute> <rng:anyName/> </rng:attribute> <rng:element> <rng:anyName/> <rng:ref name="__anyxml__"/> </rng:element> <rng:text/> </rng:choice> </rng:zeroOrMore> </rng:define> EXAMPLE: YANG statement in a module with namespace prefix "yam" anyxml data { description "Any XML content allowed here."; } is mapped to the following fragment: <rng:element name="yam:data"> <a:documentation>Any XML content allowed here</a:documentation> <rng:ref name="__anyxml__"/> </rng:element> An anyxml node is optional if there is no "mandatory true;" substatement. The <rng:element> element then MUST be wrapped in <rng:optional>, except when the 'anyxml' statement is a child of the 'choice' statement and thus forms a shorthand case for that choice (see Section 9.1.1 for details).10.2. The 'argument' Statement
This statement is not mapped to the output schema, but see the rules for handling extensions in Section 9.4.
10.3. The 'augment' Statement
As a substatement of 'uses', this statement is handled as a part of 'uses' mapping, see Section 10.57. At the top level of a module or submodule, the 'augment' statement is used for augmenting the schema tree of another YANG module. If the augmented module is not processed within the same mapping session, the top-level 'augment' statement MUST be ignored. Otherwise, the contents of the statement are added to the foreign module with the namespace of the module where the 'augment' statement appears.10.4. The 'base' Statement
This statement is ignored as a substatement of 'identity' and handled within the 'identityref' type if it appears as a substatement of that type definition, see Section 10.53.6.10.5. The 'belongs-to' Statement
This statement is not used since the processing of submodules is always initiated from the main module, see Section 10.24.10.6. The 'bit' Statement
This statement is handled within the "bits" type, see Section 10.53.4.10.7. The 'case' Statement
This statement is mapped to the <rng:group> or <rng:interleave> element, depending on whether or not the statement belongs to an definition of an RPC operation. If the argument of a sibling 'default' statement equals to ARGUMENT, the @nma:implicit attribute with the value of "true" MUST be added to that <rng:group> or <rng: interleave> element. The @nma:implicit attribute MUST NOT be used for nodes at the top-level of a non-default case (see Section 7.9.3 in [RFC6020]).10.8. The 'choice' Statement
This statement is mapped to the <rng:choice> element. If 'choice' has the 'mandatory' substatement with the value of "true", the attribute @nma:mandatory MUST be added to the <rng: choice> element with the value of ARGUMENT. This case may require
additional handling, see Section 11.2.1. Otherwise, if "mandatory true;" is not present, the <rng:choice> element MUST be wrapped in <rng:optional>. The alternatives in <rng:choice> -- mapped from either the 'case' statement or a shorthand case -- MUST NOT be defined as optional.10.9. The 'config' Statement
This statement is mapped to the @nma:config attribute, and ARGUMENT becomes its value.10.10. The 'contact' Statement
This statement SHOULD NOT be used by the mapping since the hybrid schema may be mapped from multiple YANG modules created by different authors. The hybrid schema contains references to all input modules in the Dublin Core elements <dc:source>, see Section 10.34. The original YANG modules are the authoritative sources of the authorship information.10.11. The 'container' Statement
Using the rules specified in Section 9.1.1, the mapping algorithm MUST determine whether the statement defines an optional container, and if so, insert the <rng:optional> element and make it the new PARENT. The container defined by this statement is then mapped to the <rng: element> element, which becomes a child of PARENT and uses ARGUMENT with prepended local namespace prefix as the value of its @name attribute. Finally, using the rules specified in Section 9.1.2, the mapping algorithm MUST determine whether the container is implicit, and if so, add the attribute @nma:implicit with the value of "true" to the <rng:element> element.10.12. The 'default' Statement
If this statement is a substatement of 'leaf', it is mapped to the @nma:default attribute of PARENT and ARGUMENT becomes its value. As a substatement of 'typedef', the 'default' statement is also mapped to the @nma:default attribute with the value of ARGUMENT. The placement of this attribute depends on whether or not the type definition has to be expanded when it is used:
o If the type definition is not expanded, @nma:default becomes an attribute of the <rng:define> pattern resulting from the parent 'typedef' mapping. o Otherwise, @nma:default becomes an attribute of the ancestor RELAX NG pattern inside which the expansion takes place. Details and an example are given in Section 9.2.2. Finally, as a substatement of 'choice', the 'default' statement identifies the default case and is handled within the 'case' statement, see Section 10.7. If the default case uses the shorthand notation where the 'case' statement is omitted, the @nma:implicit attribute with the value of "true" is either attached to the node representing the default case in the shorthand notation or, alternatively, an extra <rng:group> element MAY be inserted and the @nma:implicit attribute attached to it. In the latter case, the net result is the same as if the 'case' statement wasn't omitted for the default case. EXAMPLE. The following 'choice' statement in a module with namespace prefix "yam" choice leaves { default feuille; leaf feuille { type empty; } leaf hoja { type empty; } } is either mapped directly to: <rng:choice> <rng:element name="yam:feuille" nma:implicit="true"> <rng:empty/> </rng:element> <rng:element name="yam:hoja"> <rng:empty/> </rng:element/> </rng:choice>
or the default case may be wrapped in an extra <rng:group>: <rng:choice> <rng:group nma:implicit="true"> <rng:element name="yam:feuille"> <rng:empty/> </rng:element> </rng:group> <rng:element name="yam:hoja"> <rng:empty/> </rng:element/> </rng:choice>10.13. The 'description' Statement
This statement is mapped to the DTD compatibility element <a:documentation> and ARGUMENT becomes its text. In order to get properly formatted in the RELAX NG compact syntax, this element SHOULD be inserted as the first child of PARENT.10.14. The 'deviation' Statement
This statement is ignored. However, it is assumed that all deviations are known beforehand and the corresponding changes have already been applied to the input YANG modules.10.15. The 'enum' Statement
This statement is mapped to the <rng:value> element, and ARGUMENT becomes its text. All substatements except 'status' are ignored because the <rng:value> element cannot contain annotation elements, see [RNG], Section 6.10.16. The 'error-app-tag' Statement
This statement is ignored unless it is a substatement of 'must'. In the latter case, it is mapped to the <nma:error-app-tag> element. See also Section 10.35.10.17. The 'error-message' Statement
This statement is ignored unless it is a substatement of 'must'. In the latter case, it is mapped to the <nma:error-message> element. See also Section 10.35.
10.18. The 'extension' Statement
This statement is ignored. However, extensions to the YANG language MAY be mapped as described in Section 9.4.10.19. The 'feature' Statement
This statement is ignored.10.20. The 'grouping' Statement
This statement is mapped to a RELAX NG named pattern definition <rng: define>, but only if the grouping defined by this statement is used without refinements and augments in at least one of the input modules. In this case, the named pattern definition becomes a child of the <rng:grammar> element and its name is ARGUMENT mangled according to the rules specified in Section 9.2. As explained in Section 8.2, a named pattern definition MUST be placed: o as a child of the root <rng:grammar> element if the corresponding grouping is defined at the top level of an input YANG module; o otherwise as a child of the embedded <rng:grammar> element corresponding to the module in which the grouping is defined. Whenever a grouping is used with refinements and/or augments, it is expanded so that the refinements and augments may be applied in place to the prescribed schema nodes. See Section 9.2.1 for further details and an example. An implementation MAY offer the option of mapping all 'grouping' statements as named pattern definitions in the output RELAX NG schema even if they are not referenced. This is useful for mapping YANG "library" modules that typically contain only 'typedef' and/or 'grouping' statements.10.21. The 'identity' Statement
This statement is mapped to the following named pattern definition which is placed as a child of the root <rng:grammar> element:
<rng:define name="__PREFIX_ARGUMENT"> <rng:choice> <rng:value type="QName">PREFIX:ARGUMENT</rng:value> <rng:ref name="IDENTITY1"/> ... </rng:choice> </rng:define> where: PREFIX is the prefix used in the hybrid schema for the namespace of the module where the current identity is defined. IDENTITY1 is the name of the named pattern corresponding to an identity that is derived from the current identity. Exactly one <rng:ref> element MUST be present for every such identity. EXAMPLE ([RFC6020], Section 7.16.3). Consider the following identities defined in two input YANG modules: module crypto-base { namespace "http://example.com/crypto-base"; prefix "crypto"; identity crypto-alg { description "Base identity from which all crypto algorithms are derived."; } } module des { namespace "http://example.com/des"; prefix "des"; import "crypto-base" { prefix "crypto"; } identity des { base "crypto:crypto-alg"; description "DES crypto algorithm"; } identity des3 { base "crypto:crypto-alg"; description "Triple DES crypto algorithm"; } }
The identities will be mapped to the following named pattern definitions: <define name="__crypto_crypto-alg"> <choice> <value type="QName">crypto:crypto-alg</value> <ref name="__des_des"/> <ref name="__des_des3"/> </choice> </define> <define name="__des_des"> <value type="QName">des:des</value> </define> <define name="__des_des3"> <value type="QName">des:des3</value> </define>10.22. The 'if-feature' Statement
ARGUMENT together with arguments of all sibling 'if-feature' statements (with added prefixes, if missing) MUST be collected in a space-separated list that becomes the value of the @nma:if-feature attribute. This attribute is attached to PARENT.10.23. The 'import' Statement
This statement is not specifically mapped. The module whose name is in ARGUMENT has to be parsed so that the importing module is able to use its top-level groupings, typedefs and identities, and also augment the data tree of the imported module. If the 'import' statement has the 'revision' substatement, the corresponding revision of the imported module MUST be used. The mechanism for finding a given module revision is outside the scope of this document.10.24. The 'include' Statement
This statement is not specifically mapped. The submodule whose name is in ARGUMENT has to be parsed and its contents mapped exactly as if the submodule text appeared directly in the main module text. If the 'include' statement has the 'revision' substatement, the corresponding revision of the submodule MUST be used. The mechanism for finding a given submodule revision is outside the scope of this document.
10.25. The 'input' Statement
This statement is handled within 'rpc' statement, see Section 10.50.10.26. The 'key' Statement
This statement is mapped to @nma:key attribute. ARGUMENT MUST be translated so that every key is prefixed with the namespace prefix of the local module. The result of this translation then becomes the value of the @nma:key attribute.10.27. The 'leaf' Statement
This statement is mapped to the <rng:element> element and ARGUMENT with prepended local namespace prefix becomes the value of its @name attribute. If the leaf is optional, i.e., if there is no "mandatory true;" substatement and the leaf is not declared among the keys of an enclosing list, then the <rng:element> element MUST be enclosed in <rng:optional>, except when the 'leaf' statement is a child of the 'choice' statement and thus represents a shorthand case for that choice (see Section 9.1.1 for details).10.28. The 'leaf-list' Statement
This statement is mapped to a block enclosed by either the <rng: zeroOrMore> or the <rng:oneOrMore> element depending on whether the argument of 'min-elements' substatement is "0" or positive, respectively (it is zero by default). This <rng:zeroOrMore> or <rng: oneOrMore> element becomes the PARENT. <rng:element> is then added as a child element of PARENT and ARGUMENT with prepended local namespace prefix becomes the value of its @name attribute. Another attribute, @nma:leaf-list, MUST also be added to this <rng:element> element with the value of "true". If the 'leaf- list' statement has the 'min-elements' substatement and its argument is greater than one, additional attribute @nma:min-elements is attached to <rng:element> and the argument of 'min-elements' becomes the value of this attribute. Similarly, if there is the 'max- elements' substatement and its argument value is not "unbounded", attribute @nma:max-elements is attached to this element and the argument of 'max-elements' becomes the value of this attribute.
EXAMPLE. Consider the following 'leaf-list' appearing in a module with the namespace prefix "yam": leaf-list foliage { min-elements 3; max-elements 6378; ordered-by user; type string; } It is mapped to the following RELAX NG fragment: <rng:oneOrMore> <rng:element name="yam:foliage" nma:leaf-list="true" nma:ordered-by="user" nma:min-elements="3" nma:max-elements="6378"> <rng:data type="string"/> </rng:element> </rng:oneOrMore>10.29. The 'length' Statement
This statement is handled within the "string" type, see Section 10.53.10.10.30. The 'list' Statement
This statement is mapped exactly as the 'leaf-list' statement, see Section 10.28. The only difference is that the @nma:leaf-list annotation either MUST NOT be present or MUST have the value of "false". When mapping the substatements of 'list', the order of children of the list element MUST be specified so that list keys, if there are any, always appear in the same order as they are defined in the 'key' substatement and before other children, see [RFC6020], Section 7.8.5. In particular, if a list key is defined in a grouping but the list node itself is not a part of the same grouping, and the position of the 'uses' statement would violate the above ordering requirement, the grouping MUST be expanded, i.e., the 'uses' statement replaced by the grouping contents. For example, consider the following YANG fragment of a module with the prefix "yam":
grouping keygrp { leaf clef { type uint8; } } list foo { key clef; leaf bar { type string; } leaf baz { type string; } uses keygrp; } It is mapped to the following RELAX NG fragment: <rng:zeroOrMore> <rng:element name="yam:foo" nma:key="yam:clef"> <rng:element name="yam:clef"> <rng:data type="unsignedByte"/> </rng:element> <rng:interleave> <rng:element name="yam:bar"> <rng:data type="string"/> </rng:element> <rng:element name="yam:baz"> <rng:data type="string"/> </rng:element> </rng:interleave> </rng:element> </rng:zeroOrMore> Note that the "keygrp" grouping is expanded and the definition of "yam:clef" is moved before the <rng:interleave> pattern.10.31. The 'mandatory' Statement
This statement may appear as a substatement of 'leaf', 'choice', or 'anyxml' statement. If ARGUMENT is "true", the parent data node is mapped as mandatory, see Section 9.1.1. As a substatement of 'choice', this statement is also mapped to the @nma:mandatory attribute, which is added to PARENT. The value of this attribute is the argument of the parent 'choice' statement.
10.32. The 'max-elements' Statement
This statement is handled within 'leaf-list' or 'list' statements, see Section 10.28.10.33. The 'min-elements' Statement
This statement is handled within 'leaf-list' or 'list' statements, see Section 10.28.10.34. The 'module' Statement
This statement is mapped to an embedded <rng:grammar> pattern having the @nma:module attribute with the value of ARGUMENT. In addition, a <dc:source> element SHOULD be created as a child of this <rng: grammar> element and contain ARGUMENT as a metadata reference to the input YANG module. See also Section 10.49. Substatements of the 'module' statement MUST be mapped so that: o statements representing configuration/state data are mapped to descendants of the <nma:data> element; o statements representing the contents of RPC requests or replies are mapped to descendants of the <nma:rpcs> element; o statements representing the contents of event notifications are mapped to descendants of the <nma:notifications> element.10.35. The 'must' Statement
This statement is mapped to the <nma:must> element. It has one mandatory attribute @assert (with no namespace) that contains ARGUMENT transformed into a valid XPath expression (see Section 9.3). The <nma:must> element may have other subelements resulting from mapping the 'error-app-tag' and 'error-message' substatements. Other substatements of 'must', i.e., 'description' and 'reference', are ignored. EXAMPLE. YANG statement in the "dhcp" module must 'current() <= ../max-lease-time' { error-message "The default-lease-time must be less than max-lease-time"; }
is mapped to: <nma:must assert="current()<=../dhcp:max-lease-time"> <nma:error-message> The default-lease-time must be less than max-lease-time </nma:error-message> </nma:must>10.36. The 'namespace' Statement
This statement is mapped simultaneously in two ways: 1. to the @xmlns:PREFIX attribute of the root <rng:grammar> element where PREFIX is the namespace prefix specified by the sibling 'prefix' statement. ARGUMENT becomes the value of this attribute; 2. to the @ns attribute of PARENT, which is an embedded <rng: grammar> pattern. ARGUMENT becomes the value of this attribute.10.37. The 'notification' Statement
This statement is mapped to the following subtree of the <nma: notifications> element in the hybrid schema (where PREFIX is the prefix of the local YANG module): <nma:notification> <rng:element name="PREFIX:ARGUMENT"> ... </rng:element> </nma:notification> Substatements of 'notification' are mapped under <rng:element name="PREFIX:ARGUMENT">.10.38. The 'ordered-by' Statement
This statement is mapped to @nma:ordered-by attribute and ARGUMENT becomes the value of this attribute. See Section 10.28 for an example.10.39. The 'organization' Statement
This statement is ignored by the mapping because the hybrid schema may be mapped from multiple YANG modules authored by different parties. The hybrid schema SHOULD contain references to all input modules in the Dublin Core <dc:source> elements, see Section 10.34.
The original YANG modules are the authoritative sources of the authorship information.10.40. The 'output' Statement
This statement is handled within the 'rpc' statement, see Section 10.50.10.41. The 'path' Statement
This statement is handled within the "leafref" type, see Section 10.53.8.10.42. The 'pattern' Statement
This statement is handled within the "string" type, see Section 10.53.10.10.43. The 'position' Statement
This statement is ignored.10.44. The 'prefix' Statement
This statement is handled within the sibling 'namespace' statement, see Section 10.36, or within the parent 'import' statement, see Section 10.23. As a substatement of 'belongs-to' (in submodules), the 'prefix' statement is ignored.10.45. The 'presence' Statement
This statement influences the mapping of the parent container (Section 10.11): the parent container definition MUST be wrapped in <rng:optional>, regardless of its contents. See also Section 9.1.1.10.46. The 'range' Statement
This statement is handled within numeric types, see Section 10.53.9.10.47. The 'reference' Statement
This statement is mapped to <a:documentation> element and its text is set to ARGUMENT prefixed with "See: ".10.48. The 'require-instance' Statement
This statement is handled within "instance-identifier" type (Section 10.53.7).
10.49. The 'revision' Statement
The mapping uses only the most recent instance of the 'revision' statement, i.e., one with the latest date in ARGUMENT, which specifies the current revision of the input YANG module [RFC6020]. This date SHOULD be recorded, together with the name of the YANG module, in the corresponding Dublin Core <dc:source> element (see Section 10.34), for example in this form: <dc:source>YANG module 'foo', revision 2010-03-02</dc:source> The 'description' substatement of 'revision' is ignored.10.50. The 'rpc' Statement
This statement is mapped to the following subtree in the RELAX NG schema (where PREFIX is the prefix of the local YANG module): <nma:rpc> <nma:input> <rng:element name="PREFIX:ARGUMENT"> ... mapped contents of 'input' ... </rng:element> </nma:input> <nma:output"> ... mapped contents of 'output' ... </nma:output> </nma:rpc> As indicated in the schema fragment, contents of the 'input' substatement (if any) are mapped under <rng:element name="PREFIX: ARGUMENT">. Similarly, contents of the 'output' substatement are mapped under <nma:output>. If there is no 'output' substatement, the <nma:output> element MUST NOT be present. The <nma:rpc> element is a child of <nma:rpcs>.10.51. The 'status' Statement
This statement MAY be ignored. Otherwise, it is mapped to @nma: status attribute and ARGUMENT becomes its value.10.52. The 'submodule' Statement
This statement is not specifically mapped. Its substatements are mapped as if they appeared directly in the module to which the submodule belongs.
10.53. The 'type' Statement
Most YANG built-in data types have an equivalent in the XSD data type library [XSD-D] as shown in Table 4. +-----------+---------------+--------------------------------+ | YANG type | XSD type | Meaning | +-----------+---------------+--------------------------------+ | int8 | byte | 8-bit integer value | | | | | | int16 | short | 16-bit integer value | | | | | | int32 | int | 32-bit integer value | | | | | | int64 | long | 64-bit integer value | | | | | | uint8 | unsignedByte | 8-bit unsigned integer value | | | | | | uint16 | unsignedShort | 16-bit unsigned integer value | | | | | | uint32 | unsignedInt | 32-bit unsigned integer value | | | | | | uint64 | unsignedLong | 64-bit unsigned integer value | | | | | | string | string | character string | | | | | | binary | base64Binary | binary data in base64 encoding | +-----------+---------------+--------------------------------+ Table 4: YANG built-in data types with equivalents in the W3C XML Schema Type Library Two important data types of the XSD data type library -- "dateTime" and "anyURI" -- are not built-in types in YANG but instead are defined as derived types in the standard modules [RFC6021]: "date- and-time" in the "ietf-yang-types" module and "uri" in the "ietf- inet-types" module. However, the formal restrictions in the YANG type definitions are rather weak. Therefore, implementations of the YANG-to-DSDL mapping SHOULD detect these derived types in source YANG modules and map them to "dateType" and "anyURI", respectively. Details about the mapping of individual YANG built-in types are given in the following subsections.
10.53.1. The "empty" Type
This type is mapped to <rng:empty/>.10.53.2. The "boolean" Type
This built-in type does not allow any restrictions and is mapped to the following XML fragment: <rng:choice> <rng:value>true</rng:value> <rng:value>false</rng:value> </rng:choice> Note that the XSD "boolean" type cannot be used here because it allows, unlike YANG, an alternative numeric representation of boolean values: 0 for "false" and 1 for "true".10.53.3. The "binary" Type
This built-in type does not allow any restrictions and is mapped simply by inserting an <rng:data> element whose @type attribute value is set to "base64Binary" (see also Table 4).10.53.4. The "bits" Type
This type is mapped to the <rng:list> and for each 'bit' substatement the following XML fragment is inserted as a child of <rng:list>: <rng:optional> <rng:value>bit_name</rng:value> </rng:optional> where bit_name is the name of the bit as found in the argument of a 'bit' substatement.10.53.5. The "enumeration" and "union" Types
These types are mapped to the <rng:choice> element.10.53.6. The "identityref" Type
This type is mapped to the following named pattern reference: <rng:ref name="__PREFIX_BASE"/> where PREFIX:BASE is the qualified name of the identity appearing in the argument of the 'base' substatement.
For example, assume that module "des" in Section 10.21 contains the following leaf definition: leaf foo { type identityref { base crypto:crypto-alg; } } This leaf would then be mapped to the following element pattern: <element name="des:foo"> <ref name="__crypto_crypto-alg"/> </element>10.53.7. The "instance-identifier" Type
This type is mapped to <rng:data> element with @type attribute set to "string". In addition, an empty <nma:instance-identifier> element MUST be inserted as a child of PARENT. The argument of the 'require-instance' substatement, if it exists, becomes the value of the @require-instance attribute of the <nma: instance-identifier> element.10.53.8. The "leafref" Type
This type is mapped exactly as the type of the leaf given in the argument of 'path' substatement. However, if the type of the referred leaf defines a default value, this default value MUST be ignored by the mapping. In addition, @nma:leafref attribute MUST be added to PARENT. The argument of the 'path' substatement, translated according to Section 9.3, is set as the value of this attribute.10.53.9. The Numeric Types
YANG built-in numeric types are "int8", "int16", "int32", "int64", "uint8", "uint16", "uint32", "uint64", and "decimal64". They are mapped to the <rng:data> element with the @type attribute set to ARGUMENT translated according to Table 4 above. An exception is the "decimal64" type, which is mapped to the "decimal" type of the XSD data type library. Its precision and number of fractional digits are controlled with the following facets, which MUST always be present:
o "totalDigits" facet set to the value of 19. o "fractionDigits" facet set to the argument of the 'fraction- digits' substatement. The fixed value of "totalDigits" corresponds to the maximum of 19 decimal digits for 64-bit integers. For example, the statement: type decimal64 { fraction-digits 2; } is mapped to the following RELAX NG data type: <rng:data type="decimal"> <rng:param name="totalDigits">19</rng:param> <rng:param name="fractionDigits">2</rng:param> </rng:data> All numeric types support the 'range' restriction, which is mapped as follows: If the range expression consists of just a single range LO..HI, then it is mapped to a pair of data type facets: <rng:param name="minInclusive">LO</rng:param> and <rng:param name="maxInclusive">HI</rng:param> If the range consists of a single number, the values of both facets are set to this value. If LO is equal to the string "min", the "minInclusive" facet is omitted. If HI is equal to the string "max", the "maxInclusive" facet is omitted. If the range expression has multiple parts separated by "|", then the parent <rng:data> element must be repeated once for every range part and all such <rng:data> elements are wrapped in <rng:choice> element. Each <rng:data> element contains the "minInclusive" and "maxInclusive" facets for one part of the range expression as described in the previous paragraph. For the "decimal64" type, the "totalDigits" and "fractionDigits" must be repeated inside each of the <rng:data> elements.
For example, type int32 { range "-6378..0|42|100..max"; } is mapped to the following RELAX NG fragment: <rng:choice> <rng:data type="int"> <rng:param name="minInclusive">-6378</rng:param> <rng:param name="maxInclusive">0</rng:param> </rng:data> <rng:data type="int"> <rng:param name="minInclusive">42</rng:param> <rng:param name="maxInclusive">42</rng:param> </rng:data> <rng:data type="int"> <rng:param name="minInclusive">100</rng:param> </rng:data> </rng:choice> See Section 9.2.2 for further details on mapping the restrictions.10.53.10. The "string" Type
This type is mapped to the <rng:data> element with the @type attribute set to "string". The 'length' restriction is handled analogically to the 'range' restriction for the numeric types (Section 10.53.9): If the length expression has just a single range: o and if the length range consists of a single number LENGTH, the following data type facet is inserted: <rng:param name="length">LENGTH</rng:param>. o if the length range is of the form LO..HI, i.e., it consists of both the lower and upper bound. The following two data type facets are then inserted: <rng:param name="minLength">LO</rng:param> and <rng:param name="maxLength">HI</rng:param>
If LO is equal to the string "min", the "minLength" facet is omitted. If HI is equal to the string "max", the "maxLength" facet is omitted. If the length expression has of multiple parts separated by "|", then the parent <rng:data> element must be repeated once for every range part and all such <rng:data> elements are wrapped in <rng:choice> element. Each <rng:data> element contains the "length" or "minLength" and "maxLength" facets for one part of the length expression as described in the previous paragraph. Every 'pattern' restriction of the "string" data type is mapped to the "pattern" facet: <rng:param name="pattern">...</rng:param> with text equal to the argument of the 'pattern' statement. All such "pattern" facets must be repeated inside each copy of the <rng:data> element, i.e., once for each length range. For example, type string { length "1|3..8"; pattern "[A-Z][a-z]*"; } is mapped to the following RELAX NG fragment: <rng:choice> <rng:data type="string"> <rng:param name="length">1</rng:param> <rng:param name="pattern">[A-Z][a-z]*</rng:param> </rng:data> <rng:data type="string"> <rng:param name="minLength">3</rng:param> <rng:param name="maxLength">8</rng:param> <rng:param name="pattern">[A-Z][a-z]*</rng:param> </rng:data> </rng:choice>10.53.11. Derived Types
If the 'type' statement refers to a derived type, it is mapped in one of the following ways depending on whether it contains any restrictions as its substatements:
1. Without restrictions, the 'type' statement is mapped simply to the <rng:ref> element, i.e., a reference to a named pattern. If the RELAX NG definition of this named pattern has not been added to the hybrid schema yet, the corresponding type definition MUST be found and its mapping installed as a subelement of either the root or an embedded <rng:grammar> element, see Section 10.54. Even if a given derived type is used more than once in the input YANG modules, the mapping of the corresponding 'typedef' MUST be installed only once. 2. If any restrictions are present, the ancestor built-in type for the given derived type must be determined and the mapping of this base type MUST be used. Restrictions appearing at all stages of the type derivation chain MUST be taken into account and their conjunction added to the <rng:data> element that defines the basic type. See Section 9.2.2 for more details and an example.10.54. The 'typedef' Statement
This statement is mapped to a RELAX NG named pattern definition <rng: define>, but only if the type defined by this statement is used without restrictions in at least one of the input modules. In this case, the named pattern definition becomes a child of either the root or an embedded <rng:grammar> element, depending on whether or not the 'typedef' statement appears at the top level of a YANG module. The name of this named pattern definition is set to ARGUMENT mangled according to the rules specified in Section 9.2. Whenever a derived type is used with additional restrictions, the ancestor built-in type for the derived type is used instead with restrictions (facets) that are a combination of all restrictions specified along the type derivation chain. See Section 10.53.11 for further details and an example. An implementation MAY offer the option of recording all 'typedef' statements as named patterns in the output RELAX NG schema even if they are not referenced. This is useful for mapping YANG "library" modules containing only 'typedef' and/or 'grouping' statements.10.55. The 'unique' Statement
This statement is mapped to the @nma:unique attribute. ARGUMENT MUST be translated so that every node identifier in each of its components is prefixed with the namespace prefix of the local module, unless the prefix is already present. The result of this translation then becomes the value of the @nma:unique attribute.
For example, assuming that the local module prefix is "ex", unique "foo ex:bar/baz" is mapped to the following attribute/value pair: nma:unique="ex:foo ex:bar/ex:baz"10.56. The 'units' Statement
This statement is mapped to the @nma:units attribute and ARGUMENT becomes its value.10.57. The 'uses' Statement
If this statement has neither 'refine' nor 'augment' substatements, it is mapped to the <rng:ref> element, i.e., a reference to a named pattern, and the value of its @name attribute is set to ARGUMENT mangled according to Section 9.2. If the RELAX NG definition of the referenced named pattern has not been added to the hybrid schema yet, the corresponding grouping MUST be found and its mapping installed as a subelement of <rng:grammar>, see Section 10.20. Otherwise, if the 'uses' statement has any 'refine' or 'augment' substatements, the corresponding grouping must be looked up and its contents inserted under PARENT. See Section 9.2.1 for further details and an example.10.58. The 'value' Statement
This statement is ignored.10.59. The 'when' Statement
This statement is mapped to the @nma:when attribute and ARGUMENT, translated according to Section 9.3, becomes it value.10.60. The 'yang-version' Statement
This statement is not mapped to the output schema. However, an implementation SHOULD check that it is compatible with the YANG version declared by the statement (currently version 1). In the case of a mismatch, the implementation SHOULD report an error and terminate.
10.61. The 'yin-element' Statement
This statement is not mapped to the output schema, but see the rules for extension handling in Section 9.4.