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-20262026-04-24 01:22:18