Subject: RELAX NG Schema for NETCONF

From: Rob Enns <[email-masked]>
Date: Tue, 16 Nov 2004 13:50:37 -0800

Here is a RELAX NG schema for the NETCONF protocol.
It's not any shorter than the XSD that appears in the draft,
but it's somewhat easier to understand at first glance (imho).

The protocol examples in the -04 draft have all been validated 
against this schema.

I will send the compact form of this schema in another message.

thanks,
 Rob

---

<?xml version="1.0" encoding="UTF-8"?>
<grammar 
 xmlns="http://relaxng.org/ns/structure/1.0"
 datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
 ns="urn:ietf:params:xml:ns:netconf:base:1.0"
  <!--
    The message-id attribute is used in the <rpc>
    and <rpc-reply> elements.
  -->
  <define name="message-id">
    <attribute name="message-id">
      <data type="string"/>
    </attribute>
  </define>

  <!--
    The session-id element is used in the <kill-session>
    RPC and <rpc-error> elements.
  -->
  <define name="session-id">
    <element name="session-id">
      <data type="unsignedInt"/>
    </element>
  </define>

  <!--
    This pattern matches any element from any namespace.
  -->
  <define name="anyElement">
    <element>
      <anyName/>
      <zeroOrMore>
        <choice>
          <attribute>
            <anyName/>
          </attribute>
          <text/>
          <ref name="anyElement"/>
        </choice>
      </zeroOrMore>
    </element>
  </define>

  <!--
    The <config> element, used in <get-config> and
    <edit-config>.
  -->
  <define name="config">
    <zeroOrMore>
      <ref name="anyElement"/>
    </zeroOrMore>
  </define>
  
  <!--
    Names of configuration datastores.
  -->
  <define name="configName">
    <choice>
      <element name="startup">
        <empty/>
      </element>
      <element name="candidate">
        <empty/>
      </element>
      <element name="running">
        <empty/>
      </element>
    </choice>
  </define>
  
  <!--
    The <url> element, allowed if the #url capability is advertised.
  -->
  <define name="url">
    <element name="url">
      <data type="anyURI"/>
    </element>
  </define>
  
  <!--
    The <source> element.
  -->
  <define name="source">
    <element name="source">
      <choice>
        <ref name="config"/>
        <ref name="configName"/>
        <ref name="url"/>
      </choice>
    </element>
  </define>

  <!--
    The <target> element.
  -->
  <define name="target">
    <element name="target">
      <choice>
        <ref name="configName"/>
        <ref name="url"/>
      </choice>
    </element>
  </define>

  <!--
    The <filter> element, used in <get> and <get-config>.
  -->
  <define name="filter">
    <element name="filter">
      <optional>
        <attribute name="type">
          <choice>
            <value>subtree</value>
            <value>xpath</value>
          </choice>
        </attribute>
      </optional>
      <optional>
        <choice>
          <ref name="anyElement"/>
          <text/>
        </choice>
      </optional>
    </element>
  </define>

  <!--
    getConfigType defines the <get-config> rpc.
  -->
  <define name="getConfigType">
    <element name="get-config">
      <ref name="source"/>
      <optional>
        <ref name="filter"/>
      </optional>
    </element>
  </define>

  <!--
    The operation attribute, used in <edit-config>.
  -->
  <define name="operation">
    <attribute name="operation">
      <choice>
        <value>merge</value>
        <value>replace</value>
        <value>create</value>
        <value>delete</value>
      </choice>
    </attribute>
  </define>

  <!--
    The <default-operation> element, used in <edit-config>.
  -->
  <define name="default-operation">
    <element name="default-operation">
      <choice>
        <value>merge</value>
        <value>replace</value>
        <value>none</value>
      </choice>
    </element>
  </define>

  <!--
    The <test-option> element, used in <edit-config>.
  -->
  <define name="test-option">
    <element name="test-option">
      <choice>
        <value>test</value>
        <value>test-then-set</value>
        <value>set</value>
      </choice>
    </element>
  </define>

  <!--
    The <error-option> element, used in <edit-config>.
  -->
  <define name="error-option">
    <element name="error-option">
      <choice>
        <value>stop-on-error</value>
        <value>ignore-error</value>
      </choice>
    </element>
  </define>

  <!--
    editConfigType defines the <edit-config> rpc.
  -->
  <define name="editConfigType">
    <element name="edit-config">
      <ref name="target"/>
      <optional>
        <ref name="default-operation"/>
      </optional>
      <optional>
        <ref name="test-option"/>
      </optional>
      <optional>
        <ref name="error-option"/>
      </optional>
      <optional>
        <ref name="config"/>
      </optional>
    </element>
  </define>

  <!--
    copyConfigType defines the <copy-config> rpc.
  -->
  <define name="copyConfigType">
    <element name="copy-config">
      <ref name="source"/>
      <ref name="target"/>
    </element>
  </define>

  <!--
    deleteConfigType defines the <delete-config> rpc.
  -->
  <define name="deleteConfigType">
    <element name="delete-config">
      <ref name="target"/>
    </element>
  </define>

  <!--
    getType defines the <get> rpc.
  -->
  <define name="getType">
    <element name="get">
      <optional>
        <ref name="filter"/>
      </optional>
    </element>
  </define>

  <!--
    lockType defines the <lock> rpc.
  -->
  <define name="lockType">
    <element name="lock">
      <ref name="target"/>
    </element>
  </define>

  <!--
    unlockType defines the <unlock> rpc.
  -->
  <define name="unlockType">
    <element name="unlock">
      <ref name="target"/>
    </element>
  </define>

  <!--
    validateType defines the <validate> rpc.
  -->
  <define name="validateType">
    <element name="validate">
      <ref name="source"/>
    </element>
  </define>

  <!--
    commitType defines the <commit> rpc.
  -->
  <define name="commitType">
    <element name="commit">
      <optional>
        <element name="confirmed">
          <empty/>
        </element>
      </optional>
      <optional>
        <element name="confirm-timeout">
          <data type="unsignedInt"/>
        </element>
      </optional>
    </element>
  </define>

  <!--
    discardChangesType defines the <discard-changes> rpc.
  -->
  <define name="discardChangesType">
    <element name="discard-changes">
      <empty/>
    </element>
  </define>

  <!--
    closeSessionType defines the <close-session> rpc.
  -->
  <define name="closeSessionType">
    <element name="close-session">
      <empty/>
    </element>
  </define>

  <!--
    killSessionType defines the <kill-session> rpc.
  -->
  <define name="killSessionType">
    <element name="kill-session">
      <ref name="session-id"/>
    </element>
  </define>

  <!--
    rpcType defines the <rpc> element.
  -->
  <define name="rpcType">
    <choice>
      <ref name="getConfigType"/>
      <ref name="editConfigType"/>
      <ref name="copyConfigType"/>
      <ref name="deleteConfigType"/>
      <ref name="getType"/>
      <ref name="lockType"/>
      <ref name="unlockType"/>
      <ref name="validateType"/>
      <ref name="commitType"/>
      <ref name="discardChangesType"/>
      <ref name="closeSessionType"/>
      <ref name="killSessionType"/>
    </choice>
  </define>

  <!--
    The <error-type> element, used in <rpc-error>.
  -->
  <define name="error-type">
    <element name="error-type">
      <choice>
        <value>transport</value>
        <value>rpc</value>
        <value>protocol</value>
        <value>application</value>
      </choice>
    </element>
  </define>

  <!--
    The <error-tag> element, used in <rpc-error>.
  -->
  <define name="error-tag">
    <element name="error-tag">
      <choice>
        <value>TOO_BIG</value>
        <value>MISSING_ATTRIBUTE</value>
        <value>BAD_ATTRIBUTE</value>
        <value>UNKNOWN_ATTRIBUTE</value>
        <value>MISSING_ELEMENT</value>
        <value>BAD_ELEMENT</value>
        <value>UNKNOWN_ELEMENT</value>
        <value>ACCESS_DENIED</value>
        <value>LOCK_DENIED</value>
        <value>RESOURCE_DENIED</value>
        <value>ROLLBACK_FAILED</value>
        <value>DATA_EXISTS</value>
        <value>DATA_MISSING</value>
        <value>OPERATION_NOT_SUPPORTED</value>
        <value>OPERATION_FAILED</value>
        <value>PARTIAL_OPERATION</value>
      </choice>
    </element>
  </define>

  <!--
    The <error-severity> element, used in <rpc-error>.
  -->
  <define name="error-severity">
    <element name="error-severity">
      <choice>
        <value>warning</value>
        <value>error</value>
      </choice>
    </element>
  </define>

  <!--
    rpcErrorType defines the <rpc-error> element.
  -->
  <define name="rpcErrorType">
    <element name="rpc-error">
      <ref name="error-type"/>
      <ref name="error-tag"/>
      <ref name="error-severity"/>
      <optional>
        <element name="error-app-tag">
          <text/>
        </element>
      </optional>
      <optional>
        <element name="error-path">
          <text/>
        </element>
      </optional>
      <optional>
        <element name="error-message">
          <text/>
        </element>
      </optional>
      <optional>
        <element name="error-info">
          <optional>
            <element name="bad-attribute">
              <text/>
            </element>
          </optional>
          <optional>
            <element name="bad-element">
              <text/>
            </element>
          </optional>
          <optional>
            <element name="ok-element">
              <text/>
            </element>
          </optional>
          <optional>
            <element name="err-element">
              <text/>
            </element>
          </optional>
          <optional>
            <element name="noop-element">
              <text/>
            </element>
          </optional>
          <optional>
            <ref name="session-id"/>
          </optional>
          <optional>
            <ref name="anyElement"/>
          </optional>
        </element>
      </optional>
    </element>
  </define>
  
  <!--
    rpcReplyType defines the <rpc-reply> element.
  -->
  <define name="rpcReplyType">
    <choice>
      <element name="ok">
        <empty/>
      </element>
      <ref name="rpcErrorType"/>
      <element name="data">
        <optional>
          <ref name="anyElement"/>
        </optional>
      </element>
    </choice>
  </define>
  
  <!--
    helloType defines the <hello> element.
  -->
  <define name="helloType">
    <element name="capabilities">
      <oneOrMore>
        <element name="capability">
          <text/>
        </element>
      </oneOrMore>
    </element>
  </define>

  <!--
    <rpc> element
  -->
  <start combine="choice">
    <element name="rpc">
      <ref name="message-id"/>
      <ref name="rpcType"/>
    </element>
  </start>

  <!--
    <rpc-reply> element
  -->
  <start combine="choice">
    <element name="rpc-reply">
      <!--
        It is an error to send <rpc> without a message-id
        attribute, BUT if such an element is received,
        the <rpc-reply> must be sent without a message-id
        attribute. Therefore it is optional here.
      -->
      <optional>
        <ref name="message-id"/>
      </optional>
      <ref name="rpcReplyType"/>
    </element>
  </start>

  <!--
    <hello> element
  -->
  <start combine="choice">
    <element name="hello">
      <ref name="helloType"/>
    </element>
  </start>

</grammar>

--
to unsubscribe send a message to [email-masked] with
the word 'unsubscribe' in a single line as the message text body.
archive: <http://ops.ietf.org/lists/netconf/>