RELAX NG: Coding requirements for constraint modules

A structural constraint module defines the constraints for a map or topic element type. A domain constraint module defines the constraints for an element or attribute domain.

All vocabulary and constraint modules must document their @domains attribute contribution. The value of the contribution is constructed according to the rules found in domains attribute rules and syntax. The OASIS grammar files use a <domainsContribution> element to document the contribution; this element is used to help enable generation of DTD and XSD grammar files. An XML comment or <a:documentation> element can also be used.

Constraint modules are implemented by importing the constraint module into a document type shell in place of the module that the constraint modifies. The constraint module itself imports the base module to be constrained; within the import, the module redefines patterns as needed to implement the constraint.

For example, a constraint module that modifies the <section> element needs to import the base module topicMod.rng. Within that import, it will constrain the section.content pattern:
<include href="topicMod.rng">
  <define name="section.content">
    <!-- Define constrained model here -->
  </define>
</include>

For a more complete example, see strictTaskbodyConstraintMod.rng, delivered with the DITA 1.3 grammar files.

Because the constraint module imports the module that it modifies, only one constraint module can be used per vocabulary module (otherwise the module being constrained would be imported multiple times). If multiple constraints are combined for a single vocabulary module, they must be implemented in one of the following ways:
  • The constraints can be combined into a single module. For example, when combining separate constraints for <section> and <shortdesc>, a single module can be defined as follows:
    <include href="topicMod.rng">
      <define name="section.content">
        <!-- Constrained model for section -->
      </define>
      <define name="shortdesc.content">
        <!-- Constrained model for shortdesc -->
      </define>
    </include>
    
  • Constraints can be chained so that each constraint imports another, until the final constraint imports the base vocabulary module. For example, when combining separate constraints for <section>, <shortdesc>, and <li> from the base vocabulary, the <section> constraint can import the <shortdesc> constraint, which in turn imports the <li> constraint, which finally imports topicMod.rng.

Example: contribution to the @domains attribute for structural constraint module

The following code fragment specifies the contribution to the @domains attribute as (topic task strictTaskbody-c):
<moduleDesc>
  <!-- ... -->
  <moduleMetadata>
    <!-- ... -->  
    <domainsContribution>(topic task strictTaskbody-c)</domainsContribution>
  </moduleMetadata>
</moduleDesc>

Example: contribution to the @domains attribute for domain constraint module

The following code fragment illustrates the domains contribution for a constraint module that restricts the task requirements domain:
<moduleDesc>
  <!-- ... -->
  <moduleMetadata>
    <!-- ... -->   
    <domainsContribution>(topic task taskreq-d requiredReqcondsTaskreq-c)</domainsContribution>
  </moduleMetadata>
</moduleDesc>