One document matched: draft-lhotka-yang-dsdl-map-00.xml
<?xml version="1.0"?>
<?rfc toc="yes"?>
<rfc ipr="full3978" category="info">
<front>
<title abbrev="YANG-DSDL Mapping">Mapping of YANG to DSDL</title>
<author initials="L.L." surname="Lhotka" fullname="Ladislav Lhotka">
<organization>CESNET</organization>
<address>
<email>lhotka@cesnet.cz</email>
</address>
</author>
<date day="6" month="July" year="2008"/>
<area>Operations and Management</area>
<workgroup>NETMOD</workgroup>
<abstract>
<t>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.</t>
</abstract>
</front>
<middle>
<section anchor="intro" title="Introduction">
<t>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 <xref
target="YANG"/>. This language, being based on SMIng <xref
target="RFC3216"/>, builds on the experience of previous network
management systems, most notably SNMP. However, since NETCONF
chose eXtensible Markup Language <xref target="XML"/> 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.</t>
<t>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.</t>
<t>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 <xref
target="DSDL"/>. 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.</t>
<t>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 <xref
target="RNG"/>. The specification of the mapping algorithm given
below assumes that output of RELAX NG uses the XML
syntax. However, RELAX NG compact syntax <xref target="RNG-CS"/>
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.</t>
<t>In the text, we use the following typographic conventions:
<list style="symbols">
<t>YANG statement keywords are delimited by single quotes.</t>
<t>Literal values are delimited by double quotes.</t>
<t>XML element names are delimited by "<" and ">" characters.</t>
<t>Names of XML attributes are prefixed by the "@" character.</t>
</list>
</t>
</section>
<section anchor="overview" title="Overview of the Mapping Algorithm">
<t>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).</t>
<t>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 <xref
target="schema-lang"/>). 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.</t>
<t>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.</t>
<t>An implementation of the mapping algorithm MUST provide the
resulting schema(s) in at least one of the following forms:
<list style="numbers">
<t anchor="multsch">A set of separate schemas, typically in
different disk files, one for each DSDL schema
language. Non-DSDL annotations MUST be attached to the RELAX NG
schema.</t>
<t anchor="onesch">A single RELAX NG schema with elements and
attributes of the remaining DSDL schema languages and other
annotations.</t>
</list>
The first form is essentially what the DSDL standard <xref
target="DSDL"/> expects and can be readily used with existing
tools. The advantage of the second form is a more concise
representation and better comprehensibility.</t>
<t>Note that non-DSDL annotations are always embedded in the RELAX
NG schema.</t>
<t>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.</t>
<section anchor="optcont" title="Optional Content">
<t>In YANG, all leaf nodes are optional unless they contain
substatement</t>
<figure>
<artwork>
mandatory true;</artwork>
</figure>
<t>or unless they are declared as list keys.</t>
<t>Lists or leaf-lists are optional unless they contain
'min-elements' substatement with argument value greater than zero.</t>
<t>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.</t>
<t>Putting it all together, we get the following recursive rule
for containers:</t>
<t>A container is optional if and only if at least one of the
following conditions holds:
<list style="numbers">
<t>it is a container with presence;</t>
<t>none of its descendant leaf nodes is mandatory or, if
such a leaf exists, it is enclosed in an intervening
container with presence;</t>
<t>none of its descendant list or leaf-list nodes has
'min-elements' substatement with argument value greater than
zero or, if such a list or leaf-list exists, it is enclosed
in an intervening container with presence.</t>
</list></t>
<t>In RELAX NG, all elements that are optional must be
explicitly wrapped in the <optional> element.</t>
<t>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.</t>
</section>
</section>
<section anchor="schema-lang" title="Schema Languages">
<t>The mapping algorithm uses the following schema languages and
annotation types:
<list style="symbols">
<t><spanx style="emph">RELAX NG</spanx> (DSDL Part 2 <xref
target="RNG"/>) is used for representing grammatical constraints,
simple datatypes (via the W3C XML Schema Datatype Library <xref
target="XSD-D"/>), complex datatypes, restrictions of datatypes,
and YANG groupings. RELAX NG namespace is
"http://relaxng.org/ns/structure/1.0".</t>
<t><spanx style="emph">Schematron</spanx> (DSDL Part 3 <xref
target="Schtrn"/>) is used for specifying additional semantic
constraints that are either inherent to YANG (e.g., uniqueness
of list keys) or specified by the data model author (e.g., using
the 'must' statement). Schematron namespace is
"http://purl.oclc.org/dsdl/schematron".</t>
<t><spanx style="emph">Document Schema Renaming Language</spanx>
(DSRL; DSDL Part 8 <xref target="DSRL"/>) is used only for
specifying default values for YANG leaf nodes and typedefs
(cf. 'default' statement). DSRL namespace is
"http://purl.oclc.org/dsdl/dsrl".</t>
<t><spanx style="emph">Dublin Core metadata terms</spanx> <xref
target="DCMT"/> are used for general data model metadata such as
authorship information, revision date or model description. The
namespace for Dublin Core metadata terms is
"http://purl.org/dc/terms".</t>
<t><spanx style="emph">RELAX NG DTD compatibility
annotations</spanx> <xref target="RNG-DTD"/> are used for
'description' and 'reference' strings, except at the top level
of a module where Dublin Core metadata terms are used for this
purpose. The namespace for DTD compatibility annotations is
"http://relaxng.org/ns/compatibility/annotations/1.0".</t>
<t><spanx style="emph">NETMOD-specific annotations</spanx> is a
small collection of other annotations that convey additional
semantics expressed by YANG model. They are always modeled as
XML attributes attached to the RELAX NG elements that they
qualify. The namespace for NETMOD-specific annotations is
"urn:ietf:params:xml:ns:netmod:dsdl-attrib:1".</t>
</list></t>
<t>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.</t>
<t>If an implementation generates multiple DSDL schemas (output
alternative <xref format="counter" target="multsch"/> in <xref
target="overview"/>), 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
<xref format="counter" target="onesch"/> in <xref
target="overview"/>), 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.</t>
<figure>
<preamble>For example, consider the following YANG
snippet:</preamble>
<artwork>
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;
}
...
}
...
}</artwork>
</figure>
<t>If multiple schemas are generated, in this case RELAX NG,
Schematron and DSRL, the 'must' statement shall be mapped to the
following Schematron fragment:</t>
<figure>
<artwork>
<![CDATA[<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>]]></artwork>
</figure>
<t>Similarly, the 'default' statement results in the following
DSRL fragment:</t>
<figure>
<artwork>
<![CDATA[<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>]]></artwork>
</figure>
<t>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</t>
<figure>
<artwork>
<![CDATA[<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>]]></artwork>
</figure>
</section>
<section anchor="design" title="Design Considerations">
<t>This section describes the general principles and conventions
used by the mapping algorithm.</t>
<section anchor="modularity" title="Modularity">
<t>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.</t>
<t>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.</t>
<t>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.</t>
</section>
<section anchor="granularity" title="Granularity">
<t>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.</t>
<t>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.</t>
<t>We argue in <xref target="issues-aug"/> 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.</t>
</section>
<section anchor="mangling"
title="Mangled Names of RELAX NG Named Patterns">
<t>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:
<list style="symbols">
<t>Mangled names of local groupings and typedefs start with a
double underline character and names of all ancestor nodes in
the YANG data tree are recorded in the mangled name, separated
by double underlines.</t>
<t>Mangled names of imported groupings and typedefs starts
with the name of the modules where they are defined followed
by double underline followed by the local name of the grouping
or typedef.</t>
</list></t>
<t>For example, YANG content</t>
<figure>
<artwork>
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";
}</artwork>
</figure>
<t>would result in the following definitions of RELAX NG named
patterns:</t>
<figure>
<artwork>
<![CDATA[<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>]]></artwork>
</figure>
</section>
</section>
<section anchor="issues" title="Open Issues">
<t>This section collects open issues that need further discussion
within the NETMOD WG.</t>
<section anchor="rootel"
title="No Root or Multiple Root Nodes">
<t>Well-formed XML documents must have exactly one root element
(cf. <xref target="XML"/>, 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.</t>
<t>For multiple roots, the YANG specification <xref
target="YANG"/> 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.</t>
<t><xref target="schema-lang"/> 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. <xref
target="RNG"/>, 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., <xref target="Vli04"/>,
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.</t>
<t>However, a YANG data model may also allow empty instance
documents if all nodes are optional, as discussed in <xref
target="optcont"/>. This leads to an invalid RELAX NG schema
with the following <start> element:</t>
<figure>
<artwork>
<![CDATA[<start>
<optional>
...
</optional>
</start>]]></artwork>
</figure>
<t>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".</t>
</section>
<section anchor="issues-ext" title='The extension Statement'>
<t>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.</t>
<t>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.</t>
</section>
<section anchor="issues-rpc"
title='The rpc and notification statements'>
<t>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.</t>
<t>A completely analogical situation is with the 'notification'
statement that defines a NETCONF notification.</t>
</section>
<section anchor="issues-aug" title='The augment Statement'>
<t>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:</t>
<t>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 <xref target="YANG"/>). 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.</t>
<t>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</t>
<figure>
<artwork>
grouping "def-coll" {
container collector {
leaf address { ... }
leaf port { ... }
}
}
...
container export {
uses "def-coll";
augment collector {
leaf protocol { ... }
}
}</artwork>
</figure>
<t>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.</t>
<t>In RELAX NG, a similar effect can be achieved by combining
pattern definitions, schematically</t>
<figure>
<artwork>
<![CDATA[<define name="def-coll">
...original content...
</define>
...
<define name="def-coll" combine="interleave">
...added content...
</define>]]></artwork>
</figure>
<t>However, there are three notable differences:
<list style="symbols">
<t>It is the original definition that is extended. This means
that every reference to the "def-coll" pattern will use the
augmented content.</t>
<t>The two definitions can only by combined at their top
level. Therefore, the second pattern definition actually
cannot add new content inside "collector". In order to be able
to do that, the original content of "collector" must be put into
a special named pattern (cf. <xref target="granularity"/>).</t>
<t>The contents of the two definitions are "interleaved",
which means that the original and added content may appear in
any order and can even be intermixed. In contrast, the
semantics of 'augment' in YANG dictates that the added content
be placed after the original one.</t>
</list>
</t>
<t>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.</t>
<t>Finally, another practical motivation for using 'augment' may
be its 'when' substatement, which allows for conditional
content, for example</t>
<figure>
<artwork>
augment "." {
when "ifType='wireless'" {
...added content...
}
}</artwork>
</figure>
<t>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.</t>
<t>In author's opinion, the problems of the 'augment' statement
mentioned above can be mitigated by making the following changes
to YANG:
<list style="symbols">
<t>Reconsider the use of 'augment' for modifications of an
external schema. It would be better to bind the modifications
explicitly to the schema that is to be augmented.</t>
<t>Allow 'augment' to appear only as a substatement of 'uses',
along with refinements. This way, the relation between
the 'augment' and 'uses' statements will be made explicit.</t>
<t>Make the 'when' statement a general mechanism for including
conditional content, even outside 'augment'.</t>
</list>
</t>
</section>
</section>
<section anchor="stmts" title="Mapping Rules for YANG Statements">
<t>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 <spanx
style="emph">pyang</spanx> tool. It is a work in progress and the
implementation is open for discussion and changes.</t>
<t>In accord with the description of the mapping algorithm in
<xref target="overview"/>, we assume the following context:
<list style="symbols">
<t>The data structure (or object) representing the YANG
statement being mapped is stored in the "stmt" variable. In
particular, "stmt.arg" is the argument of this statement.</t>
<t>A pointer to the RELAX NG element that will become parent of
the new XML fragment representing the translation of the current
YANG statement is also available. Schematically, the context in
the RELAX NG tree looks like this:
<figure>
<artwork>
<![CDATA[<rng:parent_element>
... next new schema stuff comes here ...
</rng:parent_element>]]></artwork>
</figure></t>
<t>When we say here that a new element is inserted, it means
that it becomes a child of <rng:parent_element>. When we
say that <rng:new_element> is inserted and becomes the new
parent element, the situation changes as follows:
<figure>
<artwork>
<![CDATA[<rng:parent_element>
<rng:new_element>
... next new schema stuff comes here ...
</rng:new_element>
<rng:parent_element>]]></artwork>
</figure></t>
</list>
</t>
<t>Throughout this section, we use qualified names for all XML
elements. The mapping of prefixes to namespace URIs is shown in <xref
target="tab-ns"/>.</t>
<texttable anchor="tab-ns">
<ttcol>Prefix</ttcol>
<ttcol>Namespace URI</ttcol>
<c>a</c><c>http://relaxng.org/ns/compatibility/annotations/1.0</c>
<c>dc</c> <c>http://purl.org/dc/terms</c>
<c>dsrl</c> <c>http://purl.oclc.org/dsdl/dsrl</c>
<c>nm</c> <c>urn:ietf:params:xml:ns:netmod:dsdl-attrib:1</c>
<c>sch</c> <c>http://purl.oclc.org/dsdl/schematron</c>
</texttable>
<t>In order to avoid unnecessary complications, this section describes
the mapping algorithm for single-file output, i.e., alternative <xref
format="counter" target="onesch"/> in <xref target="overview"/>.</t>
<section anchor="anyxml" title="The anyxml Statement">
<t>At the first occurrence of this statement, the following
pattern definition is added to the RELAX NG schema (cf. <xref
target="Vli04"/>, p. 172):</t>
<figure>
<artwork>
<![CDATA[<define name="__anyxml__">
<zeroOrMore>
<choice>
<attribute>
<anyName/>
</attribute>
<element>
<anyName/>
<ref name="__anyxml__"/>
</element>
<text/>
</choice>
</zeroOrMore>
</define>]]></artwork>
</figure>
<t>Reference to this pattern is then inserted for
all 'anyxml' statements.</t>
</section>
<section anchor="argument-stmt" title="The argument Statement">
<t>Not implemented, see <xref target="issues-ext"/>.</t>
</section>
<section anchor="augment-stmt" title="The augment Statement">
<t>Not implemented, see <xref target="issues-aug"/>.</t>
</section>
<section anchor="belongs-to-stmt" title="The belongs-to Statement">
<t>Insert Dublin Core metadata term <dc:isPartOf>.</t>
</section>
<section anchor="bit-stmt" title="The bit Statement">
<t>Handled within the "bits" type, see <xref
target="bits-type"/>.</t>
</section>
<section anchor="case-stmt" title="The case Statement">
<t>Insert <rng:group> element and handle all
substatements.</t>
</section>
<section anchor="choice-stmt" title="The choice Statement">
<t>Insert <rng:choice> element and handle all
substatements.</t>
</section>
<section anchor="config-stmt" title="The config Statement">
<t>Attach attribute @nm:config to the parent element and use
stmt.arg as its value.</t>
</section>
<section anchor="contact-stmt" title="The contact Statement">
<t>Insert Dublin Core metadata term <dc:contributor> and
use stmt.arg as its content.</t>
</section>
<section anchor="container-stmt" title="The container Statement">
<t>Using the procedure outlined in <xref target="optcont"/>,
determine whether the container is optional, and if so, insert
the <rng:optional> element and make it the new parent
element.</t>
<t>Then insert <rng:element> element at the current
position and use stmt.arg as the value of its @name
attribute.</t>
<t>Then handle all substatements.</t>
</section>
<section anchor="default-stmt" title="The default Statement">
<t>Insert element <dsrl:default-content> with stmt.arg as
its content.</t>
</section>
<section anchor="description-stmt" title="The description Statement">
<t>If the statement is at the module top level, insert Dublin
Core metadata term <dc:description> and use stmt.arg as
its content.</t>
<t>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.</t>
</section>
<section anchor="enum-stmt" title="The enum Statement">
<t>Insert <rng:value> element and use stmt.arg as its
content.</t>
<t>Then handle the 'status' substatement. Other substatements
('value', 'description' and 'reference') are ignored because the
<rng:value> element cannot contain foreign elements, see
<xref target="RNG"/>, Section 6.</t>
</section>
<section anchor="error-app-tag-stmt" title="The error-app-tag Statement">
<t>Not implemented.</t>
</section>
<section anchor="error-message-stmt" title="The error-message Statement">
<t>Handled only within the 'must' statement, see <xref
target="must-stmt"/>. Ignored in other contexts.</t>
</section>
<section anchor="extension-stmt" title="The extension Statement">
<t>Not implemented, see <xref target="issues-ext"/>.</t>
</section>
<section anchor="grouping-stmt" title="The grouping Statement">
<t>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 <xref target="mangling"/>.</t>
<t>Then handle all substatements.</t>
</section>
<section anchor="import-stmt" title="The import Statement">
<t>Ignored, as it is assumed that all imported modules are
processed by the YANG parser and made available to the mapping
algorithm.</t>
</section>
<section anchor="include-stmt" title="The include Statement">
<t>Insert <rng:include> and set the value of its @href attribute
to stmt.arg concatenated with the file extension ".rng".</t>
</section>
<section anchor="input-stmt" title="The input Statement">
<t>Not implemented, see <xref target="issues-rpc"/>.</t>
</section>
<section anchor="key-stmt" title="The key Statement">
<t>Attach attribute @nm:key to the parent element and use
stmt.arg as its value.</t>
</section>
<section anchor="leaf-stmt" title="The leaf Statement">
<t>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.</t>
<t>Then insert <rng:element> element and use stmt.arg as the value
of its @name attribute.</t>
<t>Then handle all substatements.</t>
</section>
<section anchor="leaf-list-stmt" title="The leaf-list Statement">
<t>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.</t>
<t>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.</t>
<t>Then handle all remaining substatements.</t>
</section>
<section anchor="length-stmt" title="The length Statement">
<t>Handled within the "string" type, see <xref
target="string-type"/>.</t>
</section>
<section anchor="list-stmt" title="The list Statement">
<t>Handled exactly as the 'leaf-list' statement, see <xref
target="leaf-list-stmt"/>.</t>
</section>
<section anchor="mandatory-stmt" title="The mandatory Statement">
<t>Handled within the 'leaf' statement, see <xref
target="leaf-stmt"/>.</t>
</section>
<section anchor="max-elements-stmt" title="The max-elements Statement">
<t>Handled within 'leaf-list' or 'list' statements, see <xref
target="leaf-list-stmt"/>.</t>
</section>
<section anchor="min-elements-stmt" title="The min-elements Statement">
<t>Handled within 'leaf-list' or 'list' statements, see <xref
target="leaf-list-stmt"/>.</t>
</section>
<section anchor="module-stmt" title="The module Statement">
<t>This statement is not specifically handled. The mapping
algorithm starts with its substatements.</t>
</section>
<section anchor="must-stmt" title="The must Statement">
<t>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.</t>
</section>
<section anchor="namespace-stmt" title="The namespace Statement">
<t>Attach @ns attribute to the <rng:grammar> element (the root
of the RELAX NG schema) and use stmt.arg as its value.</t>
</section>
<section anchor="notification-stmt" title="The notification Statement">
<t>Not implemented, see <xref target="issues-rpc"/>.</t>
</section>
<section anchor="ordered-by-stmt" title="The ordered-by Statement">
<t>Handled within 'leaf-list' and 'list' statements, see <xref
target="leaf-list-stmt"/>.</t>
</section>
<section anchor="organization-stmt"
title="The organization Statement">
<t>Insert Dublin Core metadata term <dc:creator> and
use stmt.arg as its content.</t>
</section>
<section anchor="output-stmt" title="The output Statement">
<t>Not implemented, see <xref target="issues-rpc"/>.</t>
</section>
<section anchor="path-stmt" title="The path Statement">
<t>Handled within "keyref" type, see <xref target="keyref-type"/>.</t>
</section>
<section anchor="pattern-stmt" title="The pattern Statement">
<t>Handled within "string" type, see <xref target="string-type"/>.</t>
</section>
<section anchor="position-stmt" title="The position Statement">
<t>Not implemented.</t>
</section>
<section anchor="prefix-stmt" title="The prefix Statement">
<t>Not implemented. In RELAX NG, the elements of the target
namespace are unprefixed.</t>
</section>
<section anchor="presence-stmt" title="The presence Statement">
<t>Handled within 'container' statement, see <xref
target="container-stmt"/> and also <xref target="optcont"/>.</t>
</section>
<section anchor="range-stmt" title="The range Statement">
<t>Handled within numeric types, see <xref
target="numeric-types"/>.</t>
</section>
<section anchor="reference-stmt" title="The reference Statement">
<t>If this statement is at module top level, insert Dublin Core
metadata term <dc:BibliographicResource> and use stmt.arg
as its content.</t> <t>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.</t>
</section>
<section anchor="revision-stmt" title="The revision Statement">
<t>Insert Dublin Core metadata term <dc:issued> and
use stmt.arg as its content.</t>
</section>
<section anchor="rpc-stmt" title="The rpc Statement">
<t>Not implemented, see <xref target="issues-rpc"/>.</t>
</section>
<section anchor="status-stmt" title="The status Statement">
<t>Attach attribute @nm:status to the parent element and use
stmt.arg as its value.</t>
</section>
<section anchor="submodule-stmt" title="The submodule Statement">
<t>This statement is not specifically handled. The mapping
algorithm starts with its substatements.</t>
</section>
<section anchor="type-stmt" title="The type Statement">
<t>References to derived types are handled in the same way as
references to groupings via the 'uses' statement (<xref
target="uses-stmt"/>): <rng:ref> element is inserted with a
properly mangled name and definitions of derived types are copied
from external modules as necessary.</t>
<t>Most YANG built-in types have an equivalent in the XSD
datatype library <xref target="XSD-D"/> as shown in <xref
target="tab-types"/>.</t>
<texttable
anchor="tab-types"
title="Selected datatypes from the W3C XML Schema Type Library">
<ttcol align="left">YANG type</ttcol>
<ttcol align="left">XSD type</ttcol>
<ttcol align="left">Meaning</ttcol>
<c>int8</c><c>byte</c><c>8-bit integer value</c>
<c>int16</c><c>short</c><c>16-bit integer value</c>
<c>int32</c><c>int</c><c>32-bit integer value</c>
<c>int64</c><c>long</c><c>64-bit integer value</c>
<c>uint8</c><c>unsignedByte</c><c>8-bit unsigned integer value</c>
<c>uint16</c><c>unsignedShort</c><c>16-bit unsigned integer value</c>
<c>uint32</c><c>unsignedInt</c><c>32-bit unsigned integer value</c>
<c>uint64</c><c>unsignedLong</c><c>64-bit unsigned integer value</c>
<c>float32</c><c>float</c><c>32-bit IEEE floating-point value</c>
<c>float64</c><c>double</c><c>64-bit IEEE floating-point value</c>
<c>string</c><c>string</c><c>character string</c>
<c>boolean</c><c>boolean</c><c>"true" or "false"</c>
<c>binary</c><c>base64Binary</c><c>binary data in base64 encoding</c>
</texttable>
<t>Details about the mapping of individual YANG built-in types
are given in the following subsections.</t>
<section anchor="empty-type" title="The empty Type">
<t>Insert empty <rng:empty> element.</t>
</section>
<section anchor="boobi-types" title="The boolean and binary Types">
<t>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 <xref
target="tab-types"/>.</t>
</section>
<section anchor="ii-type" title="The instance identifier Type">
<t>This YANG built-in type has no equivalent in the XSD
datatype library and is mapped to the RELAX NG "string"
type:</t>
<figure>
<artwork>
<![CDATA[<rng:data type="string"/>]]></artwork>
</figure>
</section>
<section anchor="bits-type" title="The bits Type">
<t>Insert <rng:list> element and insert under it for each 'bit'
substatement the following XML fragment:</t>
<figure>
<artwork>
<![CDATA[<rng:optional>
<rng:value>bit_name</rng:value>
</rng:optional>]]></artwork>
</figure>
<t>where bit_name is the name of the bit as found in the
argument of the corresponding 'bit' statement.</t>
</section>
<section anchor="enuun-type"
title="The enumeration and union Types">
<t>Insert <rng:choice> and handle all substatements.</t>
</section>
<section anchor="keyref-type" title="The keyref type">
<t>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.</t>
</section>
<section anchor="numeric-types" title="The numeric Types">
<t>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 <xref
target="tab-types"/>.</t>
<t>All numeric types support the 'range' restriction, which is
handled in the following way:
<list style="symbols">
<t>If the range expression consists of a single range part,
insert the pair of RELAX NG facets
<figure>
<artwork>
<![CDATA[<rng:param name="minInclusive">...</rng:param>]]></artwork>
</figure>
and
<figure>
<artwork>
<![CDATA[<rng:param name="maxInclusive">...</rng:param>]]></artwork>
</figure>
Their contents are the lower and upper bound of the range
part, respectively. If the range part consists of a single
number, both "minInclusive" and "maxInclusive" facets use
this value as their content. If the lower bound is "min",
the "minInclusive" facet is omitted and if the upper bound
is "max", the "maxInclusive" facet is omitted.</t>
<t>If the range expression has multiple parts separated by
"|", then repeat the <rng:data> element once for every
range part and wrap them all in <rng:choice>
element. Inside each <rng:data> element, the
corresponding range part is handled as described in the
previous item.</t>
</list>
</t>
<t>For example, the 'typedef' statement</t>
<figure>
<artwork>
typedef rt {
type int32 {
range "-6378..0|42|100..max";
}
}</artwork>
</figure>
<t>translates to the following RELAX NG fragment:</t>
<figure>
<artwork>
<![CDATA[<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>]]></artwork>
</figure>
</section>
<section anchor="string-type" title="The string Type">
<t>This type is mapped by inserting the <rng:data> element with
the @type attribute set to "string".</t>
<t>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.</t>
<t>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
<figure>
<artwork>
<![CDATA[<rng:param name="pattern">...</rng:param>]]></artwork>
</figure>
if there is any, must be repeated inside each copy of the
<rng:data> element, i.e., for each length part.</t>
</section>
</section>
<section anchor="typedef-stmt" title="The typedef Statement">
<t>Handled exactly as the 'grouping' statement, see <xref
target="grouping-stmt"/>.</t>
</section>
<section anchor="unique-stmt" title="The unique Statement">
<t>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.</t>
</section>
<section anchor="units-stmt" title="The units Statement">
<t>Attach attribute @nm:units to the parent element and use
stmt.arg as its value.</t>
</section>
<section anchor="uses-stmt" title="The uses Statement">
<t>
<list style="numbers">
<t>Check whether the grouping that the statement refers to
is defined in the same module that is being translated. If
it is so, go to step <xref target="putref"
format="counter"/>.</t>
<t>[the grouping is defined in another module] If the same
grouping has been already used in the module that is being
translated, go to step <xref target="putref"
format="counter"/>.</t>
<t>[first use of an external grouping] Copy the grouping
definition from the external module and install its
translation according to <xref target="grouping-stmt"/> with a
properly mangled name (see <xref target="mangling"/>).</t>
<t anchor="putref">Insert <rng:ref> element and set its @name
attribute to stmt.arg after performing the name mangling
procedure described in <xref target="mangling"/>, taking
into account whether the grouping is local or external.</t>
</list>
</t>
<t>Handling of substatements, and in particular the refinement
statements, is not implemented yet.</t>
</section>
<section anchor="value-stmt" title="The value Statement">
<t>Not implemented.</t>
</section>
<section anchor="when-stmt" title="The when Statement">
<t>Not implemented, see <xref target="issues-aug"/>.</t>
</section>
<section anchor="yang-version-stmt" title="The yang-version Statement">
<t>Not implemented. Its stmt.arg may be checked by the mapping
algorithm in order to make sure that the module is compatible.</t>
</section>
<section anchor="yin-element-stmt" title="The yin-element Statement">
<t>Not implemented, see <xref target="issues-ext"/>.</t>
</section>
</section>
</middle>
<back>
<references>
<reference anchor='XML'
target='http://www.w3.org/TR/2006/REC-xml-20060816'>
<front>
<title>Extensible Markup Language (XML) 1.0 (Fourth Edition)</title>
<author initials='T.' surname='Bray' fullname='Tim Bray'>
<organization />
</author>
<author initials='J.' surname='Paoli' fullname='Jean Paoli'>
<organization />
</author>
<author initials='C.' surname='Sperberg-McQueen'
fullname='C. M. Sperberg-McQueen'>
<organization />
</author>
<author initials='E.' surname='Maler' fullname='Eve Maler'>
<organization />
</author>
<author initials='F.' surname='Yergeau' fullname='François Yergeau'>
<organization />
</author>
<date month='August' day='16' year='2006' />
</front>
<seriesInfo name='World Wide Web Consortium Recommendation'
value='REC-xml-20060816' />
<format type='HTML'
target='http://www.w3.org/TR/2006/REC-xml-20060816' />
</reference>
<reference anchor="XSD-D"
target='http://www.w3.org/TR/2004/REC-xmlschema-2-20041028'>
<front>
<title>XML Schema Part 2: Datatypes Second Edition</title>
<author initials='P.' surname='Biron' fullname='Paul V. Biron'>
<organization />
</author>
<author initials='A.' surname='Malhotra' fullname='Ashok Malhotra'>
<organization />
</author>
<date month='October' day='28' year='2004' />
</front>
<seriesInfo name='World Wide Web Consortium Recommendation'
value='REC-xmlschema-2-20041028' />
<format type='HTML'
target='http://www.w3.org/TR/2004/REC-xmlschema-2-20041028'
/>
</reference>
<reference anchor='YANG'>
<front>
<title>YANG - A data modeling language for NETCONF</title>
<author role="editor" initials='M' surname='Bjorklund'
fullname='Martin Bjorklund'>
<organization />
</author>
<date month='May' day='5' year='2008' />
</front>
<seriesInfo name='Internet-Draft'
value='draft-ietf-netmod-yang-00' />
<format type='TXT'
target='http://www.ietf.org/internet-drafts/draft-ietf-netmod-yang-00.txt' />
</reference>
<reference anchor="RNG-CS">
<front>
<title>RELAX NG Compact Syntax</title>
<author role="editor" fullname="James Clark" surname="Clark"
initials="J.">
<organization/>
</author>
<date month="November" day="21" year="2002"/>
</front>
<seriesInfo name="OASIS Committee Specification"
value="21 November 2002"/>
<format type="HTML"
target="http://www.oasis-open.org/committees/relax-ng/compact-20021121.html"/>
</reference>
<reference anchor="RNG-DTD">
<front>
<title>RELAX NG DTD Compatibility</title>
<author role="editor" fullname="James Clark" surname="Clark"
initials="J.">
<organization/>
</author>
<author role="editor" fullname="Murata Makoto" surname="Murata"
initials="M.">
<organization/>
</author>
<date month="December" day="3" year="2001"/>
</front>
<seriesInfo name="OASIS Committee Specification"
value="3 December 2001"/>
<format type="HTML"
target="http://relaxng.org/compatibility-20011203.html"/>
</reference>
<reference anchor="DCMT">
<front>
<title>DCMI Metadata Terms</title>
<author fullname="DCMI Usage Board">
<organization>DCMI</organization>
</author>
<date month="January" day="14" year="2008"/>
</front>
<format type="HTML"
target="http://www.dublincore.org/documents/dcmi-terms/"/>
</reference>
<reference anchor='RFC3216'>
<front>
<title>SMIng Objectives</title>
<author initials='C.' surname='Elliott' fullname='C. Elliott'>
<organization/></author>
<author initials='D.' surname='Harrington' fullname='D. Harrington'>
<organization /></author>
<author initials='J.' surname='Jason' fullname='J. Jason'>
<organization /></author>
<author initials='J.' surname='Schoenwaelder'
fullname='J. Schoenwaelder'>
<organization /></author>
<author initials='F.' surname='Strauss' fullname='F. Strauss'>
<organization /></author>
<author initials='W.' surname='Weiss' fullname='W. Weiss'>
<organization /></author>
<date year='2001' month='December' />
</front>
<seriesInfo name='RFC' value='3216' />
<format type='TXT' octets='58551'
target='http://www.ietf.org/rfc/rfc3216.txt'/>
</reference>
<reference anchor="DSDL">
<front>
<title>Document Schema Definition Languages (DSDL) - Part 1:
Overview</title>
<author fullname="ISO/IEC">
<organization>ISO/IEC</organization>
</author>
<date day="14" month="11" year="2004"/>
</front>
<seriesInfo name="ISO/IEC" value="19757-1"/>
<format type="PDF"
target="http://www.dsdl.org/0567.pdf"/>
</reference>
<reference anchor="RNG">
<front>
<title>Document Schema Definition Languages (DSDL) - Part 2:
Regular-Grammar-Based Validation - RELAX NG</title>
<author fullname="ISO/IEC">
<organization>ISO/IEC</organization>
</author>
<date year="2002"/>
</front>
<seriesInfo name="ISO/IEC" value="19757-2"/>
<format type="PDF"
target="http://www.dsdl.org/relaxng-is.pdf"/>
</reference>
<reference anchor="Schtrn">
<front>
<title>Document Schema Definition Languages (DSDL) - Part 3:
Rule-Based Validation - Schematron</title>
<author fullname="ISO/IEC">
<organization>ISO/IEC</organization>
</author>
<date year="2004"/>
</front>
<seriesInfo name="ISO/IEC" value="19757-3"/>
<format type="PDF"
target="http://www.dsdl.org/0524.pdf"/>
</reference>
<reference anchor="DSRL">
<front>
<title>Document Schema Definition Languages (DSDL) - Part 8:
Document Schema Renaming Language - DSRL</title>
<author fullname="ISO/IEC">
<organization>ISO/IEC</organization>
</author>
<date year="2006"/>
</front>
<seriesInfo name="ISO/IEC" value="19757-8"/>
<format type="PDF"
target="http://www.dsdl.org/0792.pdf"/>
</reference>
<reference anchor="Vli04">
<front>
<title>RELAX NG</title>
<author fullname="Eric van der Vlist" surname="van der Vlist"
initials="E.">
<organization/>
</author>
<date year="2004"/>
</front>
<seriesInfo name="O'Reilly" value=""/>
</reference>
</references>
<section anchor="app-dhcp"
title="Translation of the DHCP Data Model">
<t>This appendix demonstrates output of the YANG->DSDL mapping
algorithm applied to the "canonical" <eref
target="http://www.yang-central.org/twiki/bin/view/Main/DhcpTutorial">DHCP
tutorial</eref> data model. It is presented as a single-file
annotated RELAX NG schema (output alternative <xref
format="counter" target="multsch"/> in <xref
target="overview"/>).</t>
<t><xref target="xml-synt"/> shows the result of the mapping
algorithm in the RELAX NG XML syntax and <xref
target="comp-synt"/> the same in the compact syntax, which was
obtained using the <eref
target="http://thaiopensource.com/relaxng/trang.html">Trang
tool</eref>.</t>
<t>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.</t>
<section anchor="xml-synt" title="XML Syntax">
<figure>
<artwork>
<![CDATA[<?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>
]]>
</artwork>
</figure>
</section>
<section anchor="comp-synt" title="Compact Syntax">
<figure>
<artwork>
<![CDATA[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}]" }
]]>
</artwork>
</figure>
</section>
</section>
</back>
</rfc>
| PAFTECH AB 2003-2026 | 2026-04-24 01:22:18 |