TOC |
|
By submitting this Internet-Draft, each author represents that any applicable patent or other IPR claims of which he or she is aware have been or will be disclosed, and any of which he or she becomes aware will be disclosed, in accordance with Section 6 of BCP 79.
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF), its areas, and its working groups. Note that other groups may also distribute working documents as Internet-Drafts.
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as “work in progress.”
The list of current Internet-Drafts can be accessed at http://www.ietf.org/ietf/1id-abstracts.txt.
The list of Internet-Draft Shadow Directories can be accessed at http://www.ietf.org/shadow.html.
This Internet-Draft will expire on January 7, 2009.
This draft describes the algorithm and rules for mapping data models expressed in the YANG language to Document Schema Definition Languages (DSDL) with additional annotations.
1.
Introduction
2.
Overview of the Mapping Algorithm
2.1.
Optional Content
3.
Schema Languages
4.
Design Considerations
4.1.
Modularity
4.2.
Granularity
4.3.
Mangled Names of RELAX NG Named Patterns
5.
Open Issues
5.1.
No Root or Multiple Root Nodes
5.2.
The extension Statement
5.3.
The rpc and notification statements
5.4.
The augment Statement
6.
Mapping Rules for YANG Statements
6.1.
The anyxml Statement
6.2.
The argument Statement
6.3.
The augment Statement
6.4.
The belongs-to Statement
6.5.
The bit Statement
6.6.
The case Statement
6.7.
The choice Statement
6.8.
The config Statement
6.9.
The contact Statement
6.10.
The container Statement
6.11.
The default Statement
6.12.
The description Statement
6.13.
The enum Statement
6.14.
The error-app-tag Statement
6.15.
The error-message Statement
6.16.
The extension Statement
6.17.
The grouping Statement
6.18.
The import Statement
6.19.
The include Statement
6.20.
The input Statement
6.21.
The key Statement
6.22.
The leaf Statement
6.23.
The leaf-list Statement
6.24.
The length Statement
6.25.
The list Statement
6.26.
The mandatory Statement
6.27.
The max-elements Statement
6.28.
The min-elements Statement
6.29.
The module Statement
6.30.
The must Statement
6.31.
The namespace Statement
6.32.
The notification Statement
6.33.
The ordered-by Statement
6.34.
The organization Statement
6.35.
The output Statement
6.36.
The path Statement
6.37.
The pattern Statement
6.38.
The position Statement
6.39.
The prefix Statement
6.40.
The presence Statement
6.41.
The range Statement
6.42.
The reference Statement
6.43.
The revision Statement
6.44.
The rpc Statement
6.45.
The status Statement
6.46.
The submodule Statement
6.47.
The type Statement
6.47.1.
The empty Type
6.47.2.
The boolean and binary Types
6.47.3.
The instance identifier Type
6.47.4.
The bits Type
6.47.5.
The enumeration and union Types
6.47.6.
The keyref type
6.47.7.
The numeric Types
6.47.8.
The string Type
6.48.
The typedef Statement
6.49.
The unique Statement
6.50.
The units Statement
6.51.
The uses Statement
6.52.
The value Statement
6.53.
The when Statement
6.54.
The yang-version Statement
6.55.
The yin-element Statement
7.
References
Appendix A.
Translation of the DHCP Data Model
A.1.
XML Syntax
A.2.
Compact Syntax
§
Author's Address
§
Intellectual Property and Copyright Statements
TOC |
The NETMOD working group complements the results of the NETCONF WG by addressing the data modeling issues. The major item in the NETMOD charter is a new data modeling language called YANG [YANG] (Bjorklund, M., Ed., “YANG - A data modeling language for NETCONF,” May 2008.). This language, being based on SMIng [RFC3216] (Elliott, C., Harrington, D., Jason, J., Schoenwaelder, J., Strauss, F., and W. Weiss, “SMIng Objectives,” December 2001.), builds on the experience of previous network management systems, most notably SNMP. However, since NETCONF chose eXtensible Markup Language [XML] (Bray, T., Paoli, J., Sperberg-McQueen, C., Maler, E., and F. Yergeau, “Extensible Markup Language (XML) 1.0 (Fourth Edition),” August 2006.) as the method for encoding both configuration data and their envelope (RPC layer), this work can and should also benefit from the body of knowledge, standards and software tools that have been established in the XML world. To this end, YANG also provides an alternative syntax called YIN that is able to represent the same information using XML. Despite the syntactic differences, the information models of YANG and YIN are virtually identical and conversion between YANG and YIN is straightforward in both directions.
However, having data models expressed in an XML syntax is not by itself sufficient for leveraging the existing XML know-how and tools. It is also necessary to convey the meaning of YANG models and present it in a way that the existing XML tools can understand. As a matter of fact, YANG/YIN can be viewed as yet another XML schema language. While there are several aspects that make YANG models specific to the NETCONF realm, for the most part the grammatical and semantic constraints that the models express can be equivalently represented in the general-purpose XML schema languages such as W3C XML Schema, RELAX NG, Schematron and others.
Therefore, one of the chartered items of the NETMOD WG is to define a mapping from YANG to the Document Schema Definition Languages (DSDL) that is being standardized as ISO/IEC 19757 [DSDL] (ISO/IEC, “Document Schema Definition Languages (DSDL) - Part 1: Overview,” 11 2004.). The DSDL framework comprises a set of XML schema languages that address grammar rules, semantic constraints and other data modeling aspect but also, and more importantly, can do it in a coordinated and consistent way. While it is true that some DSDL parts have not been standardized yet and are still work in progress, the two crucial parts that the YANG -> DSDL mapping relies upon - RELAX NG and Schematron - already have the status of ISO/IEC Final Draft International Standard and are supported in a number of software tools.
This memo describes the algorithm for translating YANG data models to a schema (or multiple schemas) utilizing a subset of the DSDL schema languages together with a limited number of other annotations. The aim is to map as much structural, datatyping and semantic information as possible from YANG to DSDL with annotations so that the resulting schema(s) can be used with standard XML tools for a relatively comprehensive validation of the contents of configuration datastores. The most important schema language in the DSDL framework is RELAX NG [RNG] (ISO/IEC, “Document Schema Definition Languages (DSDL) - Part 2: Regular-Grammar-Based Validation - RELAX NG,” 2002.). The specification of the mapping algorithm given below assumes that output of RELAX NG uses the XML syntax. However, RELAX NG compact syntax [RNG‑CS] (Clark, J., Ed., “RELAX NG Compact Syntax,” November 2002.) is often the preferred form for perusal by human readers. A secondary goal therefore is to guarantee a reasonable level of readability of the resulting RELAX NG in the compact syntax as well, even if multiple embedded annotation types are used.
In the text, we use the following typographic conventions:
TOC |
The mapping algorithm assumes input in the form of a tree data structure representing a valid YANG module, henceforth denoted as the "YANG tree". Each node in the YANG tree is a data structure that corresponds to a single YANG statement. The node records the essential parameters of the statement (keyword, argument string) and keeps a pointer to the parent statement and a list of substatements. It is also assumed that the algorithm has access, perhaps on demand, to the parsed form of all YANG modules that the module imports (transitively).
The algorithm recursively traverses the YANG tree in preorder and constructs one or more XML trees for each of the DSDL schema languages that the algorithm generates (see Section 3 (Schema Languages)). In parallel, it keeps a pointer to the current position in each of the schema trees where new XML fragments corresponding to YANG statements get attached.
The resulting schema(s) may be internally represented in the form of a Document Object Model (DOM) or any other framework for creating and manipulating moderately sized XML trees.
An implementation of the mapping algorithm MUST provide the resulting schema(s) in at least one of the following forms:
The first form is essentially what the DSDL standard [DSDL] (ISO/IEC, “Document Schema Definition Languages (DSDL) - Part 1: Overview,” 11 2004.) expects and can be readily used with existing tools. The advantage of the second form is a more concise representation and better comprehensibility.
Note that non-DSDL annotations are always embedded in the RELAX NG schema.
An implementation SHOULD also allow the user to select a subset of schema languages and annotation types that are used for output. For example, a user might want to select pure RELAX NG without any annotations and still obtain a schema that is reasonably usable for validation.
TOC |
In YANG, all leaf nodes are optional unless they contain substatement
mandatory true;
or unless they are declared as list keys.
Lists or leaf-lists are optional unless they contain 'min-elements' substatement with argument value greater than zero.
YANG specification allows non-presence containers to be be omitted if they are empty. Containers with the 'presence' substatement are always optional since their presence or absence carries specific information.
Putting it all together, we get the following recursive rule for containers:
A container is optional if and only if at least one of the following conditions holds:
In RELAX NG, all elements that are optional must be explicitly wrapped in the <optional> element.
Therefore, the mapping algorithm MUST be able to determine whether a YANG node is optional and if so, insert the <optional> element in the RELAX NG schema.
TOC |
The mapping algorithm uses the following schema languages and annotation types:
If the YANG module contains no schema tree - for example, if it contains only definitions of grouping and typedefs - then the resulting RELAX NG schema SHOULD NOT have a <start> element.
If an implementation generates multiple DSDL schemas (output alternative 1 in Section 2 (Overview of the Mapping Algorithm)), then all such schemas MUST be valid according to the current DSDL standards. However, if the output form is a single annotated RELAX NG schema (output alternative 2 in Section 2 (Overview of the Mapping Algorithm)), certain parts of the annotating DSDL schema rules MAY be omitted, provided that the corresponding information can be unambiguously inferred, typically from the location of the annotating elements within the RELAX NG tree.
For example, consider the following YANG snippet:
module dhcp { ... container dhcp { ... leaf max-lease-time { ... }; leaf default-lease-time { ... must '$this <= ../max-lease-time' { error-message "default-lease-time must be less than max-lease-time"; } default 600; } ... } ... }
If multiple schemas are generated, in this case RELAX NG, Schematron and DSRL, the 'must' statement shall be mapped to the following Schematron fragment:
<sch:pattern> <sch:rule context="/dhcp/default-lease-time" <sch:assert test=". <= ../max-lease-time"> default-lease-time must be less than max-lease-time </sch:assert> </sch:rule> <sch:pattern>
Similarly, the 'default' statement results in the following DSRL fragment:
<dsrl:element-map> <dsrl:within>/dhcp</dsrl:within> <dsrl:name>default-lease-time</dsrl:name> <dsrl:default-content>600</dsrl:default-content> <dsrl:element-map>
In both the Schematron and DSRL fragments, the context for the rules is explicitly specified by means of an XPath expression. If we insert these rules as annotations into the RELAX NG schema, the context is implicitly defined by the location of the rules with the RELAX NG schema. Therefore, the resulting RELAX NG schema fragment can be only
<element name="default-lease-time"> ... <sch:assert test=". <= ../max-lease-time"> The default-lease-time must be less than max-lease-time </sch:assert> <dsrl:default-content>600</dsrl:default-content> </element>
TOC |
This section describes the general principles and conventions used by the mapping algorithm.
TOC |
Both YANG and RELAX NG offer means for modularity, i.e., splitting the contents into separate modules (schemas) and combining or reusing them in various ways. However, the approaches taken by YANG and RELAX NG differ. Modularity in RELAX NG is intended more for ad hoc combinations of a small number of schemas whereas YANG assumes a large set of modules similar to SNMP MIBs. In particular, RELAX NG uses a single flat namespace for all named patterns, be they local or imported, while every YANG module has its unique namespace and symbols imported by other modules remain in the namespace of their original module. Consequently, multiple YANG groupings and typedefs defined in different modules can have the same (local) identifier but still be used together in another module, but in RELAX NG this would mean a name conflict.
Therefore, the design decision for the mapping algorithm was to collect all contents in a single DSDL module even if in YANG it is distributed in several modules. Translations of foreign groupings and typedefs are installed in the importing module with appropriately mangled names - but only if they are really used by the importing module.
On the other hand, YANG submodules share the same namespace with the modules they belong to, so their modular structure can be retained in RELAX NG by using the <include> element.
TOC |
RELAX NG supports different styles of structuring the schema: One extreme, often called "Russian Doll", specifies the structure of an XML instance document in a single schema. The other extreme, the flat style, is similar to the original Data Type Definition (DTD) schema language - every XML element is introduced inside a new named pattern. In practice, some compromise between the two extremes is usually chosen.
YANG in principle supports both styles, too, but in most cases the modules are organized in a way that's closer to the "Russian Doll" style, which provides a better insight into the structure of the configuration data. Groupings are usually defined only for subtrees that are prepared for reuse via the 'uses' statement. In contrast, RELAX NG schemas tend to be much flatter, because finer granularity is in RELAX NG also needed for extensibility of the schemas - it is only possible to replace or modify schema fragments that are factored out as named patterns. For YANG this is not an issue since its 'augment' statement can delve, by using path expressions, into arbitrary depths of existing structures.
We argue in Section 5.4 (The augment Statement) that is is in general not feasible to map YANG extension mechanisms to those of RELAX NG. For this reason, the mapping keeps the granularity of the original YANG data model: definitions of named patterns in the resulting RELAX NG schema have direct counterparts in YANG groupings and definitions of complex types.
TOC |
YANG typedefs and groupings may appear in all levels of the module hierarchy and are subject to lexical scoping. Moreover, top-level symbols from external modules are imported as qualified names consisting of the external module namespace and the name of the symbol. In contrast, named patterns in RELAX NG (both local and imported) share the same namespace and their definitions may only appear at the top level of the RELAX NG schema as children of the <grammar> element. Consequently, whenever YANG groupings and typedefs are translated into RELAX NG named pattern definitions, their MUST be disambiguated in order to avoid naming conflicts. The following name mangling procedure is suggested:
For example, YANG content
import "inet-types" { prefix "inet"; } grouping "grp1" { leaf "void" { type "empty"; } } container "cont" { grouping "grp2" { leaf "address" { type "inet:ip-address"; } } uses "grp1"; uses "grp2"; }
would result in the following definitions of RELAX NG named patterns:
<define name="__grp1"> <optional> <element name="void"> <empty/> </element> </optional> </define> <define name="__cont__grp2"> <element name="address"> <ref name="inet-types__ip-address"/> </element> </define> <define name="inet-types__ip-address"> ... </define>
TOC |
This section collects open issues that need further discussion within the NETMOD WG.
TOC |
Well-formed XML documents must have exactly one root element (cf. [XML] (Bray, T., Paoli, J., Sperberg-McQueen, C., Maler, E., and F. Yergeau, “Extensible Markup Language (XML) 1.0 (Fourth Edition),” August 2006.), Section 2.1). In contrast, YANG data models may also allow multiple root nodes or no root at all. Consequently, it is impossible to translate such data models to a valid RELAX NG schema.
For multiple roots, the YANG specification [YANG] (Bjorklund, M., Ed., “YANG - A data modeling language for NETCONF,” May 2008.) recommends in Section 5.1.1 to use an extra conceptual root node such as <data> or <config>. While it is possible to include such a conceptual node in the RELAX NG schema, it would likely become an annoyance for data models with a single root. Therefore, a general solution to the problem of multiple roots should be devised.
Section 3 (Schema Languages) specifies that the resulting RELAX NG schema should not have a <start> element if the original YANG model contains no explicit data tree. Strictly speaking, this leads to an invalid RELAX NG schema (cf. [RNG] (ISO/IEC, “Document Schema Definition Languages (DSDL) - Part 2: Regular-Grammar-Based Validation - RELAX NG,” 2002.), Section 7.19) and some RELAX NG parsers indeed do complain about it. However, it is a common practice to prepare such "startless" RELAX NG schemas with definitions of reusable named patterns, see e.g., [Vli04] (van der Vlist, E., “RELAX NG,” 2004.), Chapter 10. It is thus probably no reason for concerns - it has to be understood that such schemas are not supposed to be used as stand-alone.
However, a YANG data model may also allow empty instance documents if all nodes are optional, as discussed in Section 2.1 (Optional Content). This leads to an invalid RELAX NG schema with the following <start> element:
<start> <optional> ... </optional> </start>
The problems of no root or multiple root nodes can be solved by changing YANG specification in the sense that all instances of data models must be enclosed in a fixed and mandatory container, for example "netmod-data".
TOC |
The 'extension' statement can be used for declaring new statements for the YANG language itself. Their keywords are qualified names carrying the namespace name of the module that defines them. It is not difficult to insert such extensions into the resulting RELAX NG schema because RELAX NG allows elements and attributes from different namespaces to be freely intermixed with its own elements and attributes. A straightforward option for translating such extensions is to generate the YIN representation of the extension (utilizing the 'argument' substatement of the 'extension' statement) and attach this XML subtree at the corresponding position in the RELAX NG schema tree.
It is not clear though whether it is sensible to blindly copy such extensions without knowing their semantics. For example, if the extension utilizes paths referring to the YANG model tree, this paths may become incorrect when used as XPaths in the RELAX NG tree.
TOC |
In YANG, the 'rpc' statement declares the signature of a NETCONF RPC operation - method names, input and output parameters. With this information, one can create a pair of schemas for validating protocol data units with NETCONF <rpc> and <rpc-reply> messages, but these schemas would be different from the data model for the entire configuration datastore that the rest of the YANG module is about. It is therefore not very clear whether and how to use the 'rpc' statement in the mapping algorithm.
A completely analogical situation is with the 'notification' statement that defines a NETCONF notification.
TOC |
For the translation to DSDL schemas, the most difficult YANG concept turns out to be the 'augment' statement. This is partly because it in fact serves several different purposes:
At the top level of the YANG module hierarchy, the 'augment' statement may be used to add new nodes to a foreign schema that is defined in another module, which is imported in the module where the 'augment' statement appears (see the examples in Section 7.5.14 of [YANG] (Bjorklund, M., Ed., “YANG - A data modeling language for NETCONF,” May 2008.)). In the context of the augmenting module, this 'augment' has no effect since the 'import' statement does not actually import any part of the foreign schema tree, just the top-level groupings and typedefs. Consequently, the algorithm that maps a single YANG module to DSDL should probably ignore it.
Probably the most common use of the 'augment' statement is for applying a grouping with additional content that is added at a specified location inside the grouping, for example
grouping "def-coll" { container collector { leaf address { ... } leaf port { ... } } } ... container export { uses "def-coll"; augment collector { leaf protocol { ... } } }
An minor difficulty here is that the relation between the 'augment' statement and the corresponding 'uses' is only implicit. If there are multiple 'uses' statements, one first has to figure out which of them the 'augment' applies to, i.e., by inspecting all the groupings and finding the one that has "collector" as its top node.
In RELAX NG, a similar effect can be achieved by combining pattern definitions, schematically
<define name="def-coll"> ...original content... </define> ... <define name="def-coll" combine="interleave"> ...added content... </define>
However, there are three notable differences:
As a result, the only way for translating 'uses' with 'augment' to RELAX NG seems to be to copy the grouping content to the place where it is used and augment it there.
Finally, another practical motivation for using 'augment' may be its 'when' substatement, which allows for conditional content, for example
augment "." { when "ifType='wireless'" { ...added content... } }
In DSDL schema languages, there is no direct way for specifying conditional content, but it could be simulated by adding Schematron rules that report an error if any part of the conditional content is present and the when condition is not satisfied.
In author's opinion, the problems of the 'augment' statement mentioned above can be mitigated by making the following changes to YANG:
TOC |
This section describes in each of its subsections the mapping procedure for one YANG statement, as it is currently implemented in the YANG->DSDL translator plug-in for the pyang tool. It is a work in progress and the implementation is open for discussion and changes.
In accord with the description of the mapping algorithm in Section 2 (Overview of the Mapping Algorithm), we assume the following context:
<rng:parent_element> ... next new schema stuff comes here ... </rng:parent_element>
<rng:parent_element> <rng:new_element> ... next new schema stuff comes here ... </rng:new_element> <rng:parent_element>
Throughout this section, we use qualified names for all XML elements. The mapping of prefixes to namespace URIs is shown in Table 1.
Prefix | Namespace URI |
---|---|
a | http://relaxng.org/ns/compatibility/annotations/1.0 |
dc | http://purl.org/dc/terms |
dsrl | http://purl.oclc.org/dsdl/dsrl |
nm | urn:ietf:params:xml:ns:netmod:dsdl-attrib:1 |
sch | http://purl.oclc.org/dsdl/schematron |
Table 1 |
In order to avoid unnecessary complications, this section describes the mapping algorithm for single-file output, i.e., alternative 2 in Section 2 (Overview of the Mapping Algorithm).
TOC |
At the first occurrence of this statement, the following pattern definition is added to the RELAX NG schema (cf. [Vli04] (van der Vlist, E., “RELAX NG,” 2004.), p. 172):
<define name="__anyxml__"> <zeroOrMore> <choice> <attribute> <anyName/> </attribute> <element> <anyName/> <ref name="__anyxml__"/> </element> <text/> </choice> </zeroOrMore> </define>
Reference to this pattern is then inserted for all 'anyxml' statements.
TOC |
Not implemented, see Section 5.2 (The extension Statement).
TOC |
Not implemented, see Section 5.4 (The augment Statement).
TOC |
Insert Dublin Core metadata term <dc:isPartOf>.
TOC |
Handled within the "bits" type, see Section 6.47.4 (The bits Type).
TOC |
Insert <rng:group> element and handle all substatements.
TOC |
Insert <rng:choice> element and handle all substatements.
TOC |
Attach attribute @nm:config to the parent element and use stmt.arg as its value.
TOC |
Insert Dublin Core metadata term <dc:contributor> and use stmt.arg as its content.
TOC |
Using the procedure outlined in Section 2.1 (Optional Content), determine whether the container is optional, and if so, insert the <rng:optional> element and make it the new parent element.
Then insert <rng:element> element at the current position and use stmt.arg as the value of its @name attribute.
Then handle all substatements.
TOC |
Insert element <dsrl:default-content> with stmt.arg as its content.
TOC |
If the statement is at the module top level, insert Dublin Core metadata term <dc:description> and use stmt.arg as its content.
Otherwise, insert DTD compatibility element <a:documentation>. In order to get properly formatted in the RELAX NG compact syntax, this element must be inserted as the first child of the parent element.
TOC |
Insert <rng:value> element and use stmt.arg as its content.
Then handle the 'status' substatement. Other substatements ('value', 'description' and 'reference') are ignored because the <rng:value> element cannot contain foreign elements, see [RNG] (ISO/IEC, “Document Schema Definition Languages (DSDL) - Part 2: Regular-Grammar-Based Validation - RELAX NG,” 2002.), Section 6.
TOC |
Not implemented.
TOC |
Handled only within the 'must' statement, see Section 6.30 (The must Statement). Ignored in other contexts.
TOC |
Not implemented, see Section 5.2 (The extension Statement).
TOC |
Insert <rng:define> element and set the value of its @name attribute to stmt.arg with prepended full path, i.e., names of all ancestor nodes in the YANG schema tree separated by double underlines - see Section 4.3 (Mangled Names of RELAX NG Named Patterns).
Then handle all substatements.
TOC |
Ignored, as it is assumed that all imported modules are processed by the YANG parser and made available to the mapping algorithm.
TOC |
Insert <rng:include> and set the value of its @href attribute to stmt.arg concatenated with the file extension ".rng".
TOC |
Not implemented, see Section 5.3 (The rpc and notification statements).
TOC |
Attach attribute @nm:key to the parent element and use stmt.arg as its value.
TOC |
Unless there is the "mandatory true;" substatement or unless an enclosing list declares this leaf among its keys, insert <rng:optional> element and make it the new parent element.
Then insert <rng:element> element and use stmt.arg as the value of its @name attribute.
Then handle all substatements.
TOC |
If there is a 'min-elements' substatement with argument value greater than zero, insert <rng:oneOrMore> and make it the new parent element. Otherwise insert <rng:zeroOrMore> and make it the new parent element.
Then insert <rng:element> and use stmt.arg as its value. If there is a 'min-elements' substatement with argument value greater than zero, attach attribute @nm:min-elements to the <rng:element> element and use the argument of the 'min-elements' statement as its value. If there is a 'max-elements' substatement, attach attribute @nm:max-elements to the <rng:element> element and use the argument of the 'max-elements' statement as its value. If there is an 'ordered-by' substatement, attach attribute @nm:ordered-by to the <rng:element > element and use the argument of the 'ordered-by' statement as its value.
Then handle all remaining substatements.
TOC |
Handled within the "string" type, see Section 6.47.8 (The string Type).
TOC |
Handled exactly as the 'leaf-list' statement, see Section 6.23 (The leaf-list Statement).
TOC |
Handled within the 'leaf' statement, see Section 6.22 (The leaf Statement).
TOC |
Handled within 'leaf-list' or 'list' statements, see Section 6.23 (The leaf-list Statement).
TOC |
Handled within 'leaf-list' or 'list' statements, see Section 6.23 (The leaf-list Statement).
TOC |
This statement is not specifically handled. The mapping algorithm starts with its substatements.
TOC |
Insert <sch:assert> element. The value of its @test attribute is set to stmt.arg in which all occurrences of the string "$this" are replaced by "." (single dot). If there is an 'error-message' substatement, its argument value is used as the content of <sch:assert>, otherwise the <sch:assert> element is empty.
TOC |
Attach @ns attribute to the <rng:grammar> element (the root of the RELAX NG schema) and use stmt.arg as its value.
TOC |
Not implemented, see Section 5.3 (The rpc and notification statements).
TOC |
Handled within 'leaf-list' and 'list' statements, see Section 6.23 (The leaf-list Statement).
TOC |
Insert Dublin Core metadata term <dc:creator> and use stmt.arg as its content.
TOC |
Not implemented, see Section 5.3 (The rpc and notification statements).
TOC |
Handled within "keyref" type, see Section 6.47.6 (The keyref type).
TOC |
Handled within "string" type, see Section 6.47.8 (The string Type).
TOC |
Not implemented.
TOC |
Not implemented. In RELAX NG, the elements of the target namespace are unprefixed.
TOC |
Handled within 'container' statement, see Section 6.10 (The container Statement) and also Section 2.1 (Optional Content).
TOC |
Handled within numeric types, see Section 6.47.7 (The numeric Types).
TOC |
If this statement is at module top level, insert Dublin Core metadata term <dc:BibliographicResource> and use stmt.arg as its content.
Otherwise insert <a:documentation> and use stmt.arg as its content. Within parent element children, insert it as the last of <a:documentation> elements (i.e., after translations of 'description' statements), but before any other subelements.
TOC |
Insert Dublin Core metadata term <dc:issued> and use stmt.arg as its content.
TOC |
Not implemented, see Section 5.3 (The rpc and notification statements).
TOC |
Attach attribute @nm:status to the parent element and use stmt.arg as its value.
TOC |
This statement is not specifically handled. The mapping algorithm starts with its substatements.
TOC |
References to derived types are handled in the same way as references to groupings via the 'uses' statement (Section 6.51 (The uses Statement)): <rng:ref> element is inserted with a properly mangled name and definitions of derived types are copied from external modules as necessary.
Most YANG built-in types have an equivalent in the XSD datatype library [XSD‑D] (Biron, P. and A. Malhotra, “XML Schema Part 2: Datatypes Second Edition,” October 2004.) as shown in Table 2 (Selected datatypes from the W3C XML Schema Type Library).
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 |
float32 | float | 32-bit IEEE floating-point value |
float64 | double | 64-bit IEEE floating-point value |
string | string | character string |
boolean | boolean | "true" or "false" |
binary | base64Binary | binary data in base64 encoding |
Table 2: Selected datatypes from the W3C XML Schema Type Library |
Details about the mapping of individual YANG built-in types are given in the following subsections.
TOC |
Insert empty <rng:empty> element.
TOC |
These two built-in types do not allow any restrictions and are mapped simply by inserting <rng:data> element whose @type attribute is set to stmt.arg mapped according to Table 2 (Selected datatypes from the W3C XML Schema Type Library).
TOC |
This YANG built-in type has no equivalent in the XSD datatype library and is mapped to the RELAX NG "string" type:
<rng:data type="string"/>
TOC |
Insert <rng:list> element and insert under it for each 'bit' substatement the following XML fragment:
<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 the corresponding 'bit' statement.
TOC |
Insert <rng:choice> and handle all substatements.
TOC |
As there is no suitable counterpart for the YANG built-in "keyref" type in the XSD datatype library, this type is mapped to "string" by inserting <rng:data> element with @type attribute set to "string". In addition, <sch:assert> element is inserted as child of <rng:data,> which checks that a 'list' entry with the corresponding value of the key exists.
TOC |
YANG built-in numeric types are "int8", "int16", "int32", "int64", "uint8", "uint16", "uint32", "uint64", "float32" and "float64". They are handled by inserting <rng:data> element with @type attribute set to stmt.arg mapped according to Table 2 (Selected datatypes from the W3C XML Schema Type Library).
All numeric types support the 'range' restriction, which is handled in the following way:
<rng:param name="minInclusive">...</rng:param>
<rng:param name="maxInclusive">...</rng:param>
For example, the 'typedef' statement
typedef rt { type int32 { range "-6378..0|42|100..max"; } }
translates to the following RELAX NG fragment:
<rng:define name="__rt"> <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> </rng:define>
TOC |
This type is mapped by inserting the <rng:data> element with the @type attribute set to "string".
For the 'pattern' restriction, insert <rng:param> element with @name attribute set to "pattern". The argument of the 'pattern' statement (regular expression) becomes the content of this element.
The 'length' restriction is handled in the same way as the 'range' restriction for the numeric types, with the additional twist that if the length expression has multiple parts, the "pattern" facet
<rng:param name="pattern">...</rng:param>
if there is any, must be repeated inside each copy of the <rng:data> element, i.e., for each length part.
TOC |
Handled exactly as the 'grouping' statement, see Section 6.17 (The grouping Statement).
TOC |
Insert <sch:assert> element. Its test checks that no two list items (sibling elements) have the same combination of values of leafs listed in stmt.arg. The content of the <sch:assert> element, i.e., the error message, is formed by a concatenation of "Not unique: " and stmt.arg.
TOC |
Attach attribute @nm:units to the parent element and use stmt.arg as its value.
TOC |
Handling of substatements, and in particular the refinement statements, is not implemented yet.
TOC |
Not implemented.
TOC |
Not implemented, see Section 5.4 (The augment Statement).
TOC |
Not implemented. Its stmt.arg may be checked by the mapping algorithm in order to make sure that the module is compatible.
TOC |
Not implemented, see Section 5.2 (The extension Statement).
TOC |
[XML] | Bray, T., Paoli, J., Sperberg-McQueen, C., Maler, E., and F. Yergeau, “Extensible Markup Language (XML) 1.0 (Fourth Edition),” World Wide Web Consortium Recommendation REC-xml-20060816, August 2006 (HTML). |
[XSD-D] | Biron, P. and A. Malhotra, “XML Schema Part 2: Datatypes Second Edition,” World Wide Web Consortium Recommendation REC-xmlschema-2-20041028, October 2004 (HTML). |
[YANG] | Bjorklund, M., Ed., “YANG - A data modeling language for NETCONF,” draft-ietf-netmod-yang-00 (work in progress), May 2008 (TXT). |
[RNG-CS] | Clark, J., Ed., “RELAX NG Compact Syntax,” OASIS Committee Specification 21 November 2002, November 2002. |
[RNG-DTD] | Clark, J., Ed. and M. Murata, Ed., “RELAX NG DTD Compatibility,” OASIS Committee Specification 3 December 2001, December 2001. |
[DCMT] | DCMI, “DCMI Metadata Terms,” January 2008. |
[RFC3216] | Elliott, C., Harrington, D., Jason, J., Schoenwaelder, J., Strauss, F., and W. Weiss, “SMIng Objectives,” RFC 3216, December 2001 (TXT). |
[DSDL] | ISO/IEC, “Document Schema Definition Languages (DSDL) - Part 1: Overview,” ISO/IEC 19757-1, 11 2004. |
[RNG] | ISO/IEC, “Document Schema Definition Languages (DSDL) - Part 2: Regular-Grammar-Based Validation - RELAX NG,” ISO/IEC 19757-2, 2002. |
[Schtrn] | ISO/IEC, “Document Schema Definition Languages (DSDL) - Part 3: Rule-Based Validation - Schematron,” ISO/IEC 19757-3, 2004. |
[DSRL] | ISO/IEC, “Document Schema Definition Languages (DSDL) - Part 8: Document Schema Renaming Language - DSRL,” ISO/IEC 19757-8, 2006. |
[Vli04] | van der Vlist, E., “RELAX NG,” O'Reilly , 2004. |
TOC |
This appendix demonstrates output of the YANG->DSDL mapping algorithm applied to the "canonical" DHCP tutorial data model. It is presented as a single-file annotated RELAX NG schema (output alternative 1 in Section 2 (Overview of the Mapping Algorithm)).
Appendix A.1 (XML Syntax) shows the result of the mapping algorithm in the RELAX NG XML syntax and Appendix A.2 (Compact Syntax) the same in the compact syntax, which was obtained using the Trang tool.
The long regular expressions for IP addresses etc. would exceed the limit of 72 characters per line, so they were replaced by a dummy text. Other than that, the results of the automatic translations were not changed.
TOC |
<?xml version="1.0" encoding="UTF-8"?> <grammar xmlns="http://relaxng.org/ns/structure/1.0" xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" xmlns:dc="http://purl.org/dc/terms" xmlns:dsrl="http://purl.oclc.org/dsdl/dsrl" xmlns:nm="urn:ietf:params:xml:ns:netmod:dsdl-attrib:1" xmlns:sch="http://purl.oclc.org/dsdl/schematron" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" ns="http://example.com/ns/dhcp"> <dc:creator>yang-central.org</dc:creator> <dc:description>Partial data model for DHCP, based on the config of the ISC DHCP reference implementation.</dc:description> <dc:source>YANG module 'dhcp' (automatic translation)</dc:source> <start> <optional> <element name="dhcp"> <a:documentation>configuration and operational parameters for a DHCP server.</a:documentation> <optional> <element name="max-lease-time" nm:units="seconds"> <data type="unsignedInt"/> <dsrl:default-content>7200</dsrl:default-content> </element> </optional> <optional> <element name="default-lease-time" nm:units="seconds"> <data type="unsignedInt"/> <sch:assert test=". <= ../max-lease-time">The default-lease-time must be less than max-lease-time</sch:assert> <dsrl:default-content>600</dsrl:default-content> </element> </optional> <ref name="__subnet-list"/> <optional> <element name="shared-networks"> <zeroOrMore> <element name="shared-network" nm:key="name"> <element name="name"> <data type="string"/> </element> <ref name="__subnet-list"/> </element> </zeroOrMore> </element> </optional> <optional> <element name="status" nm:config="false"> <zeroOrMore> <element name="leases" nm:key="address"> <element name="address"> <ref name="inet-types__ip-address"/> </element> <optional> <element name="starts"> <ref name="yang-types__date-and-time"/> </element> </optional> <optional> <element name="ends"> <ref name="yang-types__date-and-time"/> </element> </optional> <optional> <element name="hardware"> <optional> <element name="type"> <choice> <value>ethernet</value> <value>token-ring</value> <value>fddi</value> </choice> </element> </optional> <optional> <element name="address"> <ref name="yang-types__phys-address"/> </element> </optional> </element> </optional> </element> </zeroOrMore> </element> </optional> </element> </optional> </start> <define name="inet-types__ip-address"> <choice> <ref name="inet-types__ipv4-address"/> <ref name="inet-types__ipv6-address"/> </choice> </define> <define name="inet-types__ipv4-address"> <data type="string"> <param name="pattern">... IPv4 address regexp ...</param> </data> </define> <define name="inet-types__ipv6-address"> <data type="string"> <param name="pattern">... IPv6 address regexp ...</param> </data> </define> <define name="yang-types__date-and-time"> <data type="string"> <param name="pattern">... date-and-time regexp ...</param> </data> </define> <define name="yang-types__phys-address"> <data type="string"/> </define> <define name="__subnet-list"> <a:documentation>A reusable list of subnets</a:documentation> <zeroOrMore> <element name="subnet" nm:key="net"> <element name="net"> <ref name="inet-types__ip-prefix"/> </element> <element name="range"> <optional> <element name="dynamic-bootp"> <a:documentation>Allows BOOTP clients to get addresses in this range</a:documentation> <empty/> </element> </optional> <element name="low"> <ref name="inet-types__ip-address"/> </element> <element name="high"> <ref name="inet-types__ip-address"/> </element> </element> <optional> <element name="dhcp-options"> <a:documentation> Options in the DHCP protocol </a:documentation> <zeroOrMore nm:ordered-by="user"> <element name="router"> <a:documentation> See: RFC 2132, sec. 3.8 </a:documentation> <ref name="inet-types__host"/> </element> </zeroOrMore> <optional> <element name="domain-name"> <a:documentation> See: RFC 2132, sec. 3.17 </a:documentation> <ref name="inet-types__domain-name"/> </element> </optional> </element> </optional> <optional> <element name="max-lease-time" nm:units="seconds"> <data type="unsignedInt"/> <dsrl:default-content>7200</dsrl:default-content> </element> </optional> </element> </zeroOrMore> </define> <define name="inet-types__ip-prefix"> <choice> <ref name="inet-types__ipv4-prefix"/> <ref name="inet-types__ipv6-prefix"/> </choice> </define> <define name="inet-types__ipv4-prefix"> <data type="string"> <param name="pattern">... IPv4 prefix regexp ...</param> </data> </define> <define name="inet-types__ipv6-prefix"> <data type="string"> <param name="pattern">... IPv6 prefix regexp ...</param> </data> </define> <define name="inet-types__host"> <choice> <ref name="inet-types__ip-address"/> <ref name="inet-types__domain-name"/> </choice> </define> <define name="inet-types__domain-name"> <data type="string"> <param name="pattern">([\p{L}\p{N}]+\.)*[\p{L}\p{N}]</param> </data> </define> </grammar>
TOC |
default namespace = "http://example.com/ns/dhcp" namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0" namespace dc = "http://purl.org/dc/terms" namespace dsrl = "http://purl.oclc.org/dsdl/dsrl" namespace nm = "urn:ietf:params:xml:ns:netmod:dsdl-attrib:1" namespace sch = "http://purl.oclc.org/dsdl/schematron" dc:creator [ "yang-central.org" ] dc:description [ "Partial data model for DHCP, based on the config of\x{a}" ~ "the ISC DHCP reference implementation." ] dc:source [ "YANG module 'dhcp' (automatic translation)" ] start = ## configuration and operational parameters for a DHCP server. element dhcp { [ nm:units = "seconds" ] element max-lease-time { xsd:unsignedInt >> dsrl:default-content [ "7200" ] }?, [ nm:units = "seconds" ] element default-lease-time { xsd:unsignedInt >> sch:assert [ test = ". <= ../max-lease-time" "The default-lease-time must be less than max-lease-time" ] >> dsrl:default-content [ "600" ] }?, __subnet-list, element shared-networks { [ nm:key = "name" ] element shared-network { element name { xsd:string }, __subnet-list }* }?, [ nm:config = "false" ] element status { [ nm:key = "address" ] element leases { element address { inet-types__ip-address }, element starts { yang-types__date-and-time }?, element ends { yang-types__date-and-time }?, element hardware { element type { "ethernet" | "token-ring" | "fddi" }?, element address { yang-types__phys-address }? }? }* }? }? inet-types__ip-address = inet-types__ipv4-address | inet-types__ipv6-address inet-types__ipv4-address = xsd:string { pattern = "... IPv4 address regexp ..." } inet-types__ipv6-address = xsd:string { pattern = "... IPv6 address regexp ..." } yang-types__date-and-time = xsd:string { pattern = "... date-and-time regexp ..." } yang-types__phys-address = xsd:string ## A reusable list of subnets __subnet-list = [ nm:key = "net" ] element subnet { element net { inet-types__ip-prefix }, element range { ## Allows BOOTP clients to get addresses in this range element dynamic-bootp { empty }?, element low { inet-types__ip-address }, element high { inet-types__ip-address } }, ## Options in the DHCP protocol element dhcp-options { [ nm:ordered-by = "user" ] ( ## See: RFC 2132, sec. 3.8 element router { inet-types__host }*), ## See: RFC 2132, sec. 3.17 element domain-name { inet-types__domain-name }? }?, [ nm:units = "seconds" ] element max-lease-time { xsd:unsignedInt >> dsrl:default-content [ "7200" ] }? }* inet-types__ip-prefix = inet-types__ipv4-prefix | inet-types__ipv6-prefix inet-types__ipv4-prefix = xsd:string { pattern = "... IPv4 prefix regexp ..." } inet-types__ipv6-prefix = xsd:string { pattern = "... IPv6 prefix regexp ..." } inet-types__host = inet-types__ip-address | inet-types__domain-name inet-types__domain-name = xsd:string { pattern = "([\p{L}\p{N}]+\.)*[\p{L}\p{N}]" }
TOC |
Ladislav Lhotka | |
CESNET | |
Email: | lhotka@cesnet.cz |
TOC |
Copyright © The IETF Trust (2008).
This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.
This document and the information contained herein are provided on an “AS IS” basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the procedures with respect to rights in RFC documents can be found in BCP 78 and BCP 79.
Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr.
The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org.