Protocol Message Structure

DTD

An OPS protocol message is an XML document, which satisfies the following Document Type Declaration (DTD).

<!--
(C) Copyright 2016, Tucows Inc.
All Rights Reserved

OPS Message Definition

-->
<!-- Envelope -->
<!ELEMENT OPS_envelope (header,body)>
<!-- header part -->
<!ELEMENT header (version)>
<!-- body part -->
<!ELEMENT body (data_block)>
<!-- data block -->
<!ELEMENT data_block (dt_assoc | dt_array |
                      dt_scalar| dt_scalarref)>
<!-- data types -->
<!ELEMENT dt_assoc (dt_assoc | dt_array|
                    dt_scalar | dt_scalarref|
                    (item)*)>
<!ELEMENT dt_array (dt_assoc | dt_array |
                    dt_scalar | dt_scalarref |
                    (item)*)>
<!ELEMENT dt_scalar (#PCDATA | dt_assoc | dt_array |
                     dt_scalar | dt_scalarref)*>
<!ELEMENT dt_scalarref (#PCDATA | dt_assoc | dt_array |
                        dt_scalar | dt_scalarref)*>
<!ELEMENT item (#PCDATA |
                   dt_assoc | dt_array |
                   dt_scalar | dt_scalarref)*>
                   
<!ATTLIST item
       key   CDATA #REQUIRED
       class CDATA #IMPLIED         >
<!ELEMENT version (#PCDATA)>
<!-- document information entities -->
<!ENTITY company 'Tucows'>
<!ENTITY copyright '2000, Tucows'>

Description

The preamble of an OPS message must contain encoding and DOCTYPE information specifying the correct DTD (ops.dtd).

<?xml version='1.0' encoding='UTF-8' standalone='no' ?>
<!DOCTYPE OPS_envelope SYSTEM 'ops.dtd'>

The start and end of an OPS message 'envelope' are delimited by <OPS_envelope> and </OPS_envelope> tags.

<OPS_envelope>
  ?
  ?
  ?
</OPS_envelope>

A message consists of two basic parts: a header and a body. The header is delimited by

and and contains information that is related to protocol transport. Currently the OPS protocol version is supported. It is delimited by and tags.

The body is delimited by and tags. Currently the body can only contain one component, which is the 'data_block'. The data block contains an XML representation of a data structure, which in turn contains the information being passed by the process. The data block is delimited by <data_block> and </data_block> tags.

<OPS_envelope>
  <header>
?
  </header>
  <body>
    <data_block>
?
    </data_block>
  </body>
</OPS_envelope>

The data structure within the data block is a represented according to data type. The following data types are supported:

  • associative array (hash): <dt_assoc></dt_assoc>
  • array: <dt_array></dt_array>
  • array or associative array elements: <item key='' [class='']>

Where key is the name of the key used to access the element. For an array, it is an integer (0...N). For an associative array, it is a string.

<dt_assoc>
    <item key='firstname'>Tom</item>
     <item key='lastname'>Jones</item>
    </dt_assoc>
<dt_array>
    <item key='0'>example1.com</item>
     <item key='1'>example2.com</item>
    </dt_array>

The class attribute is optional. If specified, it refers to a class name that can be used to reconstruct the data into an object when decoded.

The actual details of this are implementation specific. For example, for a Perl implementation the class name would be used to bless the underlying associative array (hash), back into an object.

<dt_array>
      <item key='0' class='myClass'>
        <dt_assoc>
          <item key='firstname'>Tom</item>
              <item key='lastname'>Jones</item>
            </dt_assoc>
      </item>
    </dt_array>
  • scalars (for example, strings, integers): <dt_scalar></dt_scalar>
  • scalar reference: <dt_scalarref></dt_scalarref>

Data types can be arbitrarily nested. For example, you could have an array of an array of associative arrays. Any complex data type can be represented, provided the base data type is an array or an associative array.

OPS message examples

This example shows an OPS message that encodes an associative array that contains an array of values:

<?xml version='1.0' encoding='UTF-8' standalone='no' ?>
<!DOCTYPE OPS_envelope SYSTEM 'ops.dtd'>
<OPS_envelope>
  <header>
    <version>1.0</version>
  </header>
  <body>
    <data_block>
      <dt_assoc>
        <item key='domain_list'>
          <dt_array>
            <item key='0'>ns1.example.com</item>
            <item key='1'>ns2.example.com</item>
            <item key='2'>ns3.example.com</item>
          </dt_array>
      </dt_assoc>
    </data_block>
  </body>
</OPS_envelope>

This example shows an OPS message that encodes an associative array that contains other associative arrays:

<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<OPS_envelope>
    <header>
        <version>1.0</version>
    </header>
    <body>
        <data_block>
            <dt_assoc>
                <dt_assoc>
                    <item key="owner">
                        <dt_assoc>
                            <item key="first_name">Tom</item>
                            <item key="last_name">Jones</item>
                        </dt_assoc>
                    </item>
                    <item key="tech">
                        <dt_assoc>
                            <item key="first_name">Anne</item>
                            <item key="last_name">Smith</item>
                        </dt_assoc>
                    </item>
                </dt_assoc>
            </dt_assoc>
        </data_block>
    </body>
</OPS_envelope>

This example shows an OPS message that encodes a scalar value:

<?xml version='1.0' encoding='UTF-8' standalone='no' ?>
<!DOCTYPE OPS_envelope SYSTEM 'ops.dtd'>
<OPS_envelope>
  <header>
    <version>1.0</version>
  </header>
  <body>
    <data_block>
      <dt_scalar>Tom Jones</dt_scalar>
   </data_block>
  </body>
</OPS_envelope>