Coding practices for DITA grammar files
This section is non-normative.
This section contains information about creating modular DTD- or RELAX NG-based grammar files. It explains how document-type shells, specialization modules, and element-configuration modules (constraint and expansion) are organized.
File naming conventions
This section is non-normative.
The OASIS DITA Technical Committee uses certain conventions for the names of XML grammar files. We suggest using these conventions as a way to facilitate the interchange of grammar files.
- Globally unique identifiers
-
Vocabulary modules that are intended for use outside of a narrowly-restricted context should have one or more associated, globally-unique names by which the modules can be referenced without regard to their local storage location. The globally-unique names can be public identifiers, URNs, or absolute URLs.
- Document-type shells
-
Document-type shells should be given a name that distinguishes their name, owner, or purpose, for example, acme-concept.dtd. The document-type shells that are provided by the DITA Technical Committee typically use the root element of the primary specialization as the basis for the file name. If necessary, a qualifier such as base is prepended to the name of the root element.
- Module names
-
For structural modules, the module name should be the element type name of the top-level topic or map type that is defined by the module, such as "topic" or "map".
For element- or attribute-domain modules, the module name should be a name that reflects the subject domain to which the domain applies, such as "highlight" or "software". Domain module names should be sufficiently unique that they are unlikely to conflict with any other domains.
In addition, each element- or attribute-domain module has a short name that is used to construct entity names that are used in associated declarations. Modules can also have abbreviated names that further shorten the short name, for example "hi-d" for the "highlight" domain, where "highlight" is the short name and "hi-d" is the abbreviated name.
DTD coding requirements
This section is non-normative.
This section explains how to implement DTD-based document-type shells, specializations, and element-configuration modules (constraint and expansion).
DTD: Use of entities
This section is non-normative.
DITA-based DTDs use entities to implement specialization and element configuration. Therefore, an understanding of entities is critical when working with DTD-based document-type shells, vocabulary modules, or element-configuration modules (constraint and expansion).
Entities can be defined multiple times within a single document type, but only the first definition is effective. How entities work shapes DTD coding practices. The following list describes a few of the more important entities that are used in DITA DTDs:
- Elements defined as entities
-
Every element in a DITA DTD is defined as an entity. When elements are added to a content model, they are added using the entity. This enables extension with domain specializations.
Example
This section is non-normative.
For example, the entity
%ph;
usually just means the<ph>
element, but it can be defined in a document-type shell to mean "<ph>
plus the elements from the highlighting domain". Because the document-type shell places that entity definition before the usual definition, every element that includes%ph;
in its content model now includes<ph>
plus every element in the highlighting domain that is specialized from<ph>
. - Content models defined as entities
-
Every element in a DITA DTD defines its content model using an entity. This enables element configuration.
Example
This section is non-normative.
For example, the content model for the<p>
element is set to%ph.content;
, and the%ph.content;
entity defines the actual content model. A constraint module then can redefine the%ph.content;
entity to remove selected elements from the content model, or an expansion module can redefine the%ph.content;
entity to add elements to the content model. - Attribute sets defined as entities
-
Every element name in a DITA DTD defines its attributes using a parameter entity. This enables element configuration.
Example
This section is non-normative.
For example, the attribute list for the<ph>
element is set to%ph.attributes;
, and the%ph.attributes;
entity defines the actual attribute list. A constraint module then can redefine the entity to remove attributes from the attribute list, or an expansion module can redefine the entity to add attributes to the attribute list.
DTD: Coding requirements for document-type shells
This section is non-normative.
A DTD-based document-type shell is organized into sections. Each section contains entity declarations that follow specific coding rules.
The DTD-based approach to configuration, specialization, and element configuration (constraint and expansion) relies heavily upon parameter entities. Several of the parameter entities that are declared in document-type shells contain references to other parameter entities. Because parameter entities must be declared before they are used, the order of the sections in a DTD-based document-type shell is significant.
A DTD-based document-type shell contains the following sections:
- Topic [or map] entity declarations
- Domain constraint integration
- Domain entity declarations
- Domain attributes declarations
- Domain extensions
- Domain attribute extensions
- Topic nesting override
- Specializations attribute override
- Element-type configuration integration
- Topic [or map] element integration
- Domain element integration
Each of the sections in a DTD-based document-type shell follows a pattern. These patterns help ensure that the shell follows XML parsing rules for DTDs. They also establish a modular design that simplifies creation of new document-type shells.
- Topic [or map] entity declarations
-
This section declares and references an external parameter entity for each of the following items:
- The entity declaration module (.ent file) for the top-level topic or map type that the document-type shell configures
- The entity declaration modules for any additional structural modules that are used by the document-type shell
The parameter entity is named
typeName-dec
.Example
This section is non-normative.
In the following example, the entity declaration module for the
<concept>
specialization is integrated into a document-type shell:<!-- ============================================================= --> <!-- TOPIC ENTITY DECLARATIONS --> <!-- ============================================================= --> <!ENTITY % concept-dec PUBLIC "-//OASIS//ENTITIES DITA 2.0 Concept//EN" "concept.ent" >%concept-dec;
- Domain constraint integration
-
This section declares and references an external parameter entity for each domain-constraint module that is integrated into the document-type shell.
The parameter entity is named
descriptorDomainName-c-dec
.Example
This section is non-normative.
In the following example, the entity file for a constraint module that reduces the highlighting domain to a subset is integrated in a document-type shell:
<!-- ============================================================= --> <!-- DOMAIN CONSTRAINT INTEGRATION --> <!-- ============================================================= --> <!ENTITY % HighlightingDomain-c-dec PUBLIC "-//ACME//ENTITIES DITA Highlighting Domain Constraint//EN" "acme-HighlightingDomainConstraint.mod" >%basic-HighlightingDomain-c-dec;
- Domain entity declarations
-
This section declares and references an external parameter entity for each element-domain module that is integrated into the document-type shell.
The parameter entity is named
shortDomainName-dec
.Example
This section is non-normative.
In the following example, the entity file for the highlighting domain is included in a document-type shell:
<!-- ============================================================= --> <!-- DOMAIN ENTITY DECLARATIONS --> <!-- ============================================================= --> <!ENTITY % hi-d-dec PUBLIC "-//OASIS//ENTITIES DITA 2.0 Highlight Domain//EN" "highlightDomain.ent" >%hi-d-dec;
- Domain attributes declarations
-
This section declares and references an external parameter entity for each attribute domain that is integrated into the document-type shell.
The parameter entity is named
domainNameAtt-dec
.Example
This section is non-normative.
In the following example, the entity file for the
@deliveryTarget
attribute domain is included in a document-type shell:<!-- ============================================================= --> <!-- DOMAIN ATTRIBUTES DECLARATIONS --> <!-- ============================================================= --> <!ENTITY % deliveryTargetAtt-d-dec PUBLIC "-//OASIS//ENTITIES DITA 2.0 Delivery Target Attribute Domain//EN" "deliveryTargetAttDomain.ent" >%deliveryTargetAtt-d-dec;
- Domain extensions
-
This section declares and references a parameter entity for each element that is extended by one or more domain modules. These entities are used by the element-domain modules that are declared later in the document-type shell to redefine the content models. Redefining the content models adds domain specializations wherever the base element is allowed.
Example
This section is non-normative.
In the following example, the entity for the
<pre>
element is redefined to add specializations from the programming, software, and user interface domains:<!-- ============================================================= --> <!-- DOMAIN EXTENSIONS --> <!-- ============================================================= --> <!ENTITY % pre "pre | %pr-d-pre; | %sw-d-pre; | %ui-d-pre;">
- Domain attribute extensions
-
This section redefines the parameter entity for each attribute domain that is integrated globally into the document-type shell. The redefinition adds an extension to the parameter entity for the relevant attribute.
Example
This section is non-normative.
In the following example, the parameter entities for the
@base
and@props
attributes are redefined to include the@newfrombase
,@othernewfrombase
,@new
, and@othernew
attributes:<!-- ============================================================= --> <!-- DOMAIN ATTRIBUTE EXTENSIONS --> <!-- ============================================================= --> <!ENTITY % base-attribute-extensions "%newfrombaseAtt-d-attribute; %othernewfrombaseAtt-d-attribute;"> <!ENTITY % props-attribute-extensions "%newAtt-d-attribute; %othernewAtt-d-attribute;">
- Topic nesting override
-
This section redefines the entity that controls topic nesting for each topic type that is integrated into the document-type shell.
The parameter entity is named
topictype-info-types
.The definition usually is an "OR" list of the topic types that can be nested in the parent topic type. Use the literal root-element name, not the corresponding parameter entity. Topic nesting can be disallowed completely by specifying the
<no-topic-nesting>
element.Example
This section is non-normative.
In the following example, the parameter entity specifies that
<concept>
can nest any number of<concept>
or<myTopicType>
topics, in any order:<!-- ============================================================= --> <!-- TOPIC NESTING OVERRIDE --> <!-- ============================================================= --> <!ENTITY % concept-info-types "concept | myTopicType">
- Specializations attribute override
-
This section redefines the
included-domains
entity to include the text entity for each attribute domain that is included in the document-type shell. The redefinition sets the effective value of the@specializations
attribute for the top-level document type that is configured by the document-type shell.Example
This section is non-normative.
In the following example, parameter entities are included for the DITA conditional-processing attributes:
<!-- ============================================================= --> <!-- SPECIALIZATIONS ATTRIBUTE OVERRIDE --> <!-- ============================================================= --> <!ENTITY included-domains "&audienceAtt-d-att; &deliveryTargetAtt-d-att; &otherpropsAtt-d-att; &platformAtt-d-att; &productAtt-d-att;" >
- Element-type configuration integration
-
This section declares and references the parameter entity for each element-configuration module (constraint and expansion) that is integrated into the document-type shell.
The parameter entity is named
descriptionElement-c-def
.Example
This section is non-normative.
In the following example, the module that constrains the content model for the
<taskbody>
element is integrated into the document-type shell for strict task:<!ENTITY % strictTaskbody-c-def PUBLIC "-//OASIS//ELEMENTS DITA 2.0 Strict Taskbody Constraint//EN" "strictTaskbodyConstraint.mod" >%strictTaskbody-c-def;
- Topic [or map] element integration
-
This section declares and references an external parameter entity for the element declaration module (.mod file) for each structural module that is integrated into the document-type shell.
The parameter entity is named
structuralType-type
.The structural modules are included in ancestry order, so that the parameter entities that are used in an ancestor module are available for use in specializations. When a structural module depends on elements from a vocabulary module that is not part of its ancestry, the module upon which the structural module has a dependency (and any ancestor modules not already included) need to be included before the module with a dependency.
Example
This section is non-normative.
In the following example, the structural modules that are required by the troubleshooting topic are integrated into the document-type shell:
<!-- ============================================================= --> <!-- TOPIC ELEMENT INTEGRATION --> <!-- ============================================================= --> <!ENTITY % topic-type PUBLIC "-//OASIS//ELEMENTS DITA 2.0 Topic//EN" "../../base/dtd/topic.mod" >%topic-type; <!ENTITY % task-type PUBLIC "-//OASIS//ELEMENTS DITA 2.0 Task//EN" "task.mod" >%task-type; <!ENTITY % troubleshooting-type PUBLIC "-//OASIS//ELEMENTS DITA 2.0 Troubleshooting//EN" "troubleshooting.mod" >%troubleshooting-type;
- Domain element integration
-
This section declares and references an external parameter entity for each element domain that is integrated into the document-type shell.
The parameter entity is named
domainName-def
.Example
This section is non-normative.
In the following example, the element-definition file for the highlighting domain is integrated into the document-type shell:
<!-- ============================================================= --> <!-- DOMAIN ELEMENT INTEGRATION --> <!-- ============================================================= --> <!ENTITY % hi-d-def PUBLIC "-//OASIS//ELEMENTS DITA 2.0 Highlight Domain//EN" "highlightDomain.mod" >%hi-d-def;
If a structural module depends on a domain, the domain module needs to be included before the structural module. This erases the boundary between the final two sections of the DTD-based document-type shell, but it is necessary to ensure that modules are embedded after their dependencies. Technically, the only solid requirement is that both domain and structural modules be declared after all other modules that they specialize from or depend on.
DTD: Coding requirements for structural and element-domain modules
This section is non-normative.
This topic covers general coding requirements for defining element types in both structural and element-domain vocabulary modules.
Module files
A vocabulary module that defines a structural or element-domain specialization is composed of two files:
- Definition module file
- This (.mod) file declares the element names, content models, and attribute lists for the element types that are defined in the vocabulary module.
- Entity declaration file
- This (.ent) file declares the general and parameter entities that are used to integrate the vocabulary module into a document-type shell.
Element definitions
A structural or element-domain vocabulary module contains a declaration for each element type that is named by the module. While the XML standard allows content models to refer to undeclared element types, the DITA standard does not permit this. All element types or attribute lists that are named within a vocabulary module are declared in one of the following objects:
- The vocabulary module
- A base module of which the vocabulary module is a direct or indirect specialization
- (For structural modules) A required domain module
The following components make up a single element definition in a DITA DTD-based vocabulary module.
- Element name entities
-
For each element type, there is a parameter entity with a name that matches the element-type name. The value is the element-type name.
Example
This section is non-normative.
For example:
<!ENTITY % topichead "topichead">
The parameter entity provides a layer of abstraction when setting up content models. It can be redefined in a document-type shell in order to create domain extensions or implement element configuration (constraint and expansion).
Element name entities for a vocabulary module typically are grouped together at the top of the vocabulary module. They can occur in any order.
- Content-model parameter entity
-
For each element type, there is a parameter entity that defines the content model. The name of the parameter entity is
tagname.content
, and the value is the content model definition.Example
This section is non-normative.
For example:
<!ENTITY % topichead.content "((%topicmeta;)?, (%data.elements.incl; | %navref; | %topicref;)*) ">
- Attribute-list parameter entity
-
For each element type, there is a parameter entity that declares the attributes that are available on the element. The name of the parameter entity is
tagname.attributes
, and the value is a list of the attributes that are used by the element type (except for@class
).Example
This section is non-normative.
For example:
<!ENTITY % topichead.attributes "keys CDATA #IMPLIED %topicref-atts; %univ-atts;" >
Consistent use and naming of the
tagname.content
parameter entity enables the use of element-configuration modules (constraint and expansion) to redefine the content model. - Element declaration
-
For each element type, there is an element declaration that consists of a reference to the content-model parameter entity.
Example
This section is non-normative.
For example:
<!ELEMENT topichead %topichead.content;>
- Attribute list declaration
-
For each element type, there is an attribute-list declaration that consists of a reference to the attribute-list parameter entity.
Example
This section is non-normative.
For example:
<!ATTLIST topichead %topichead.attributes;>
- Specialization attribute declarations
-
A vocabulary module defines a
@class
attribute for every element that is declared in the module. The value of the attribute is constructed according to the rules in The class attribute rules and syntax.Example
This section is non-normative.
For example, the
ATTLIST
definition for the<topichead>
element (a specialization of the<topicref>
element in the base map type) includes the definition of the@class
attribute, as follows:<!ATTLIST topichead class CDATA "+ map/topicref mapgroup-d/topichead ">
Definition of the <topichead>
element
This section is non-normative.
The following code sample shows how the <topichead>
element is
defined in mapGroup.mod. Ellipses indicate where the code sample has
been snipped for brevity.
<!-- ============================================================= -->
<!-- ELEMENT NAME ENTITIES -->
<!-- ============================================================= -->
<!ENTITY % topichead "topichead" >
...
<!-- ============================================================= -->
<!-- ELEMENT DECLARATIONS -->
<!-- ============================================================= -->
<!-- LONG NAME: Topichead -->
<!ENTITY % topichead.content
"((%topicmeta;)?,
(%data.elements.incl; |
%navref; |
%topicref;)*)"
>
<!ENTITY % topichead.attributes
"keys
CDATA
#IMPLIED
%topicref-atts;
%univ-atts;"
>
<!ELEMENT topichead %topichead.content;>
<!ATTLIST topichead %topichead.attributes;>
...
<!-- ============================================================= -->
<!-- SPECIALIZATION ATTRIBUTE DECLARATIONS -->
<!-- ============================================================= -->
...
<!ATTLIST topichead class CDATA "+ map/topicref mapgroup-d/topichead ">
<!-- ================== End of DITA Map Group Domain ==================== -->
DTD: Coding requirements for structural modules
This section is non-normative.
This topic covers general coding requirements for DTD-based structural modules.
Required topic and map element attributes
The topic or map element type sets the @ditaarch:DITAArchVersion
attribute to the version of
DITA in use, typically by referencing the
arch-atts
parameter entity. It also sets the
@specializations
attribute to the
included-domains
entity.
The @DITAArchVersion
and @specializations
attributes give
processors a reliable way to check the architecture version and look up the list of
attribute domains that are available in the document type.
Example
This section is non-normative.
The following example shows how the @DITAArchVersion
and
@specializations
attributes are defined for the
<concept>
element in DITA 2.0. Ellipses indicate where the code
is snipped for brevity:
<!-- ============================================================= -->
<!-- ELEMENT DECLARATIONS -->
<!-- ============================================================= -->
...
<!-- LONG NAME: Concept -->
...
<!ATTLIST concept
%concept.attributes;
%arch-atts;
specializations CDATA "&included-domains;">
Controlling nesting in topic types
A structural module that defines a new topic
type typically uses a parameter entity to define a default
for what topic types are permitted to nest. When this is done
consistently, a shell that includes multiple structural modules can
set common nesting rules for all topic types by setting
%info-types;
entity.
The following rules apply when using parameter entities to control nesting.
- Parameter entity name
-
The name of the parameter entity is the topic element name plus the
-info-types
suffix.Example
This section is non-normative.
For example, the name of the parameter entity for the concept topic is
concept-info-types
. - Parameter entity value
-
To set up default topic nesting rules, set the entity to the desired topic elements. The default topic nesting is used when a document-type shell does not set up different rules.
Example
This section is non-normative.
For example, the following parameter entity sets up default nesting so that
<concept>
will nest only other<concept>
topics:<!-- ============================================================= --> <!-- ELEMENT DECLARATIONS --> <!-- ============================================================= --> <!ENTITY % concept-info-types "%info-types;" >
Example
This section is non-normative.
As an additional example, the following parameter entity sets up a default that will not allow any nesting:
<!ENTITY % glossentry-info-types "no-topic-nesting">
- Content model of the root element
-
The last position in the content model defined for the root element of a topic type should be the
topictype-info-types
parameter entity.A document-type shell then can control how topics are allowed to nest for this specific topic type by redefining the
topictype-info-types
entity for each topic type.Example
This section is non-normative.
For example, with the following content model defined for
<concept>
, a document-type shell that uses the concept specialization can control which topics are nested in<concept>
by redefining theconcept-info-types
parameter entity:<!ENTITY % concept.content "((%title;), (%abstract; | %shortdesc;)?, (%prolog;)?, (%conbody;)?, (%related-links;)?, (%concept-info-types;)*)" >
In certain cases, you do not need to use an info-types
parameter entity to
control topic nesting:
- If you want a specialized topic type to disallow nested topics, regardless of context, it can be defined without any entity or any nested topics.
- If you want a specialized topic type to only allow specific nesting patterns, such as allowing only other topic types that are defined in the same module, it can nest those topics directly in the same way that other nested elements are defined.
DTD: Coding requirements for element-domain modules
This section is non-normative.
The vocabulary modules that define element domains have an additional coding requirement. The entity declaration file must include a parameter entity for each element that the domain extends.
- Parameter entity name
-
The name of the parameter entity is the abbreviation for the domain, followed by a hyphen ("-") and the name of the element that is extended.
Example
This section is non-normative.
For example, the name of the parameter entity for the highlighting domain that extends the
<ph>
element ishi-d-ph
. - Parameter entity value
-
The value of the parameter entity is a list of the specialized elements that can occur in the same locations as the extended element. Each element is separated by the vertical line ( | ) symbol.
Example
This section is non-normative.
For example, the value of the
%hi-d-ph;
parameter entity is"b | u | i | line-through | overline | tt | sup | sub"
.
Example
This section is non-normative.
The following code sample shows the parameter entity for the highlight domain, as declared in highlightDomain.ent:
<!-- ============================================================= -->
<!-- ELEMENT EXTENSION ENTITY DECLARATIONS -->
<!-- ============================================================= -->
<!ENTITY % hi-d-ph "b | i | line-through | overline | sup | sub | tt | u">
<!-- ================ End DITA Highlight Domain ================== -->
DTD: Coding requirements for attribute-domain modules
This section is non-normative.
The vocabulary modules that define attribute domains have
additional coding requirements. The module must include a parameter
entity for the new attribute, which can be referenced in document-type
shells, as well as a general entity that
specifies the contribution to the @specializations
attribute for the attribute domain.
The name of an attribute domain is the name of the attribute
plus Att. For example, for the attribute named
@deliveryTarget
, the attribute-domain name is "deliveryTargetAtt". The
attribute-domain name is used to construct entity names for the domain.
- Parameter entity name and value
- The name of the parameter entity is the attribute-domain name,
followed by the literal
-d-attribute
. The value of the parameter entity is a DTD declaration for the attribute. - General entity name and value
- The general entity name is the
attribute-domain name, followed by the literal
-d-Att
. The value of the text entity is the@specializations
attribute contribution for the module. See The specializations attribute rules and syntax for details on how to construct this value.
Example
This section is non-normative.
The @deliveryTarget
attribute can be defined in a vocabulary module using
the following two entities.
<!ENTITY % deliveryTargetAtt-d-attribute
"deliveryTarget CDATA #IMPLIED"
>
<!ENTITY deliveryTargetAtt-d-att "@props/deliveryTarget" >
DTD: Coding requirements for element-configuration modules
This section is non-normative.
Element-configuration modules (constraint and expansion) have specific coding requirements.
The tagname.attributes
parameter
entity
When the attribute list for an
element is constrained or expanded, there is a declaration of the
tagname.attributes
parameter entity that defines the modified attributes.
Example
This section is non-normative.
The following list provides examples for both constraint and expansion modules:
- Constraint module
-
The following parameter entity defines a constrained attributes list for the
<note>
element that removes most of the values defined for@type
. It also removes@othertype
:<!ENTITY % note.attributes "type (attention | caution | note ) #IMPLIED %univ-atts;">
The following parameter entity restricts the highlighting domain to
<b>
and<i>
:<!ENTITY % HighlightingDomain-c-ph "b | i" >
- Expansion module
-
The following parameter entity defines a new attribute intended for use with various table elements:
<!ENTITY % cellPurposeAtt-d-attribute-expansion "cell-purpose (sale | out-of-stock | new | last-chance | inherit | none) #IMPLIED" >
For expansion modules, note the following considerations.
The tagname.attributes
parameter entity can be defined in an attribute-specialization
module, or it can be defined directly in the expansion module.
The tagname.content
parameter entity
When the content model for an element is constrained or expanded, there is a
declaration of the tagname.content
parameter
entity that defines the modified content model.
Example
This section is non-normative.
The following list provides examples for both constraint and expansion modules:
- Constraint module
-
The following parameter entity defines a more restricted content model for
<topic>
, in which the<shortdesc>
element is required.<!ENTITY % topic.content "((%title;), (%shortdesc;), (%prolog;)?, (%body;)?, (%topic-info-types;)*)" >
Note that replacing a base element with domain extensions is a form of constraint that can be accomplished directly in the document-type shell. No constraint module is required.
In the following example, the<pre>
base type is removed from the entity declaration, effectively allowing specializations of<pre>
but not<pre>
itself.<!ENTITY % pre "%pr-d-pre; | %sw-d-pre; | %ui-d-pre;">
- Expansion module
-
The redefinition of the content model references the parameter entity that was defined in the element-specialization module.
The following code sample shows the entity declaration file for an element-specialization module that defines a
<section-shortdesc>
element, which is intended to be added to the content model of<section>
:<!ENTITY % section-shortdesc "section-shortdesc">
When the content model for
<section>
is redefined in the expansion module, it references the parameter entity defined in the entities file for the element specialization:<!ENTITY % section.content "(#PCDATA | %dl; | %div; | %fig; | %image; | %note; | %ol; | %p; | %simpletable; | %ul; | %title; | %draft-comment;| %sectionShortdesc;)*" >
Note that this expansion module also constrains the content model of
<section>
to only include certain block elements.
RELAX NG coding requirements
This section is non-normative.
This section explains how to implement RNG-based document-type shells, specializations, and element-configuration modules (constraints and expansions).
If you plan to generate DTD- or XSD-based modules from RELAX NG modules, avoid RELAX NG features that cannot be translated into DTD or XSD constructs. Such features include lexical patterns for attributes and elements, interleave patterns, and context-specific patterns for content models or attribute lists.
When RELAX NG is used directly for DITA document validation, the document-type shells for those documents can integrate constraint modules that use the full power of RELAX NG to enforce constraints that cannot be enforced by DTDs or XSDs.
RELAX NG: Overview of coding requirements
This section is non-normative.
This topic contains general information about the self-integrating aspect of domain specialization modules, RELAX NG grammar files, and the two RNG syntaxes
Self-integration of RELAX NG domain modules
Domain modules coded in RELAX NG are self-integrating; they automatically add to the content models and attribute lists that they extend. This aspect of RELAX NG results in the following coding practices:
- Each domain module consists of a single file, unlike the two required for DTDs.
- The domain modules directly extend elements, unlike DTDs, which rely on an extra file and extensions within the document-type shell.
- Element-configuration modules (constraint and expansion) directly include the modules that they extend, which means that just by referencing an element-configuration module, the document-type shell gets everything it needs to redefine a vocabulary module.
General RELAX NG information
- Use the
<a:documentation>
element anywhere that foreign elements are allowed by RELAX NG. The<a:documentation>
element refers to the<documentation>
element type from thehttp://relaxng.org/ns/compatibility/annotations/1.0
as defined by the DTD compatibility specification. The prefix "a" is used by convention. - Use
<div>
to group pattern declarations. - Include embedded Schematron rules or any other foreign
vocabulary. Processors can ignore any foreign vocabularies
within DITA grammars that are not in the
http://relaxng.org/ns/compatibility/annotations/1.0
orhttp://dita.oasis-open.org/architecture/2005/
namespaces.
Syntaxes for RELAX NG grammars
The RELAX NG specification defines two syntaxes for RELAX NG grammars: the XML syntax and the compact syntax. The two syntaxes are functionally equivalent, and either syntax can be reliably converted into the other by using, for example, the open-source Trang tool.
The DITA coding requirements are defined for the RELAX NG XML syntax. Document-type shells, vocabulary modules, and element-configuration modules (constraints and expansion) that use the RELAX NG compact syntax can use the same organizational structures as those defined for the RELAX NG XML syntax.
DITA practitioners can author DITA modules using one RELAX NG syntax, and then use tools to generate modules in the other syntax. The resulting RELAX NG modules are equivalent if there is a one-to-one file correspondence.
RELAX NG: Coding requirements for document-type shells
This section is non-normative.
A RNG-based document-type shell is organized into sections; each section follows a pattern. These patterns help ensure that the shell follows XML parsing rules for RELAX NG; they also establish a modular design that simplifies creation of new document-type shells.
An RNG-based document-type shell contains the following sections:
- Root element declaration
- specializations attribute
- Element-type configuration integration
- Module inclusions
- ID-defining element overrides
- Root element declaration
-
Document-type shells use the RELAX NG start declaration to specify the root element of the document type. The
<start>
element defines the root element, using a reference to atagname.element
pattern.For example:<div> <a:documentation>ROOT ELEMENT DECLARATION</a:documentation> <start combine="choice"> <ref name="topic.element"/> </start> </div>
@specializations
attribute-
This section lists the tokens that attribute-domain and element-configuration modules contribute to the
@specializations
attribute.For example:<div> <a:documentation>SPECIALIZATIONS ATTRIBUTE</a:documentation> <define name="specializations-att"> <optional> <attribute name="specializations" a:defaultValue="@props/audience @props/deliveryTarget @props/otherprops @props/platform @props/product" /> </optional> </define> </div>
- Element-type configuration integration
-
This section of the document-type shell contains includes for element-type configuration modules (constraint and expansion). Because an element-configuration module imports the module that it overrides, any module that is configured in this section (including the base topic or map modules) is left out of the following "Module inclusion" section.
The following code sample shows the section of an RNG-based document-type shell that redefines the
<taskbody>
element to create the strict task topic.<div> <a:documentation>ELEMENT-TYPE CONFIGURATION INTEGRATION</a:documentation> <include href="strictTaskbodyConstraintMod.rng"/> </div>
- Module inclusions
-
This section of the RNG-based document-type shell includes all unconstrained domain or structural modules.
For example:<div> <a:documentation>MODULE INCLUSIONS</a:documentation> <include href="topicMod.rng"> <define name="topic-info-types"> <ref name="topic.element"/> </define> </include> <include href="audienceAttDomain.rng" dita:since="2.0"/> <include href="deliveryTargetAttDomain.rng"/> <include href="otherpropsAttDomain.rng" dita:since="2.0"/> <include href="platformAttDomain.rng" dita:since="2.0"/> <include href="productAttDomain.rng" dita:since="2.0"/> <include href="alternativeTitlesDomain.rng" dita:since="2.0"/> <include href="emphasisDomain.rng" dita:since="2.0"/> <include href="hazardstatementDomain.rng"/> <include href="highlightDomain.rng"/> <include href="utilitiesDomain.rng"/> </div>
- ID-defining element overrides
-
This section declares any element in the document type that uses an
@id
attribute with an XML data type of ID. This declaration is required in order to prevent RELAX NG parsers from issuing errors.If the document-type shell includes domains for foreign vocabularies such as SVG or MathML, this section also includes exclusions for the namespaces used by those domains.
For example, the following code sample is from an RNG-based document-type shell for a task topic. It declares that both the<topic>
and<task>
elements have an@id
attribute with an XML data type of ID. These elements and any elements in the SVG or MathML namespaces are excluded from the "any" pattern by being placed within the<except>
element:<div> <a:documentation> ID-DEFINING-ELEMENT OVERRIDES </a:documentation> <define name="any"> <zeroOrMore> <choice> <ref name="idElements"/> <element> <anyName> <except> <name>topic</name> <name>task</name> <nsName ns="http://www.w3.org/2000/svg"/> <nsName ns="http://www.w3.org/1998/Math/MathML"/> </except> </anyName> <zeroOrMore> <attribute> <anyName/> </attribute> </zeroOrMore> <ref name="any"/> </element> <text/> </choice> </zeroOrMore> </define> </div>
RELAX NG: Coding requirements for structural and element-domain modules
This section is non-normative.
This topic covers general coding requirements for defining element types in both structural and element-domain vocabulary modules.
Module files
Each RELAX NG vocabulary module consists of a single module file.
Element definitions
A structural or element-domain vocabulary module contains a declaration for each element type that is named in the module. While the XML standard allows content models to refer to undeclared element types, the DITA standard does not permit it. All element types or attribute lists that are named in a vocabulary module are declared in one of the following objects:
- The vocabulary module
- A base module of which the vocabulary module is a direct or indirect specialization
- (If the vocabulary module is a structural module) A required domain or structural module
The element type patterns are organized into the following sections:
- Element type name patterns
-
For each element type that is declared in the vocabulary module, there is a pattern whose name is the element type name and whose content is a reference to the
tagname.element
pattern for the element type.Example
This section is non-normative.
The following example shows the pattern for the
<b>
element:<div> <a:documentation>ELEMENT TYPE NAME PATTERNS</a:documentation> <!-- ... --> <define name="b"> <ref name="b.element"/> </define> <!-- ... --> </div>
The element-type name pattern provides a layer of abstraction that facilitates redefinition. The element-type name patterns are referenced from content model and domain extension patterns. Specialization modules can re-declare the patterns to include specializations of the type, allowing the specialized types in all contexts where the base type is allowed.
The declarations can occur in any order.
- Common content-model patterns
- Structural and element-domain modules can include a section that defines the patterns that contribute to the content models of the element types that are defined in the module.
- Common attribute sets
- Structural and element-domain modules can include a section that defines patterns for attribute sets that are common to one or more of the element types that are defined in the module.
- Element type declarations
-
For each element type that is declared in the vocabulary module, the following set of patterns are used to define the content model and attributes for the element type. Each set of patterns typically is grouped within a
<div>
element.tagname.content
- Defines the complete content model for the element tagname. The content model pattern can be overridden in element-configuration modules (constraint and expansion).
tagname.attributes
- Defines the complete attribute list for the element tagname,
except for
@class
. The attribute list declaration can be overridden in element-configuration modules (constraint and expansion). tagname.element
- Provides the actual element-type definition. It contains an
<element>
element whose@name
value is the element type name and whose content is a reference to thetagname.content
andtagname.attlist
patterns. tagname.attlist
- Contains an additional
attribute-list pattern with a
@combine
attribute set to the value interleave. This pattern contains only a reference to thetagname.attributes
pattern. This pattern enables the integration of attribute specializations.
Example
This section is non-normative.
The following example shows the declaration for the
<topichead>
element, including the definition for each pattern described above.<div> <a:documentation>Topic Head</a:documentation> <define name="topichead.content"> <optional> <ref name="topicmeta"/> </optional> <zeroOrMore> <choice> <ref name="data.elements.incl"/> <ref name="navref"/> <ref name="topicref"/> </choice> </zeroOrMore> </define> <define name="topichead.attributes"> <optional> <attribute name="keys"/> </optional> <ref name="topicref-atts"/> <ref name="univ-atts"/> </define> <define name="topichead.element"> <element name="topichead"> <a:documentation/> <ref name="topichead.attlist"/> <ref name="topichead.content"/> </element> </define> <define name="topichead.attlist" combine="interleave"> <ref name="topichead.attributes"/> </define> </div>
- idElements pattern contribution
-
Element types that declare the
@id
attribute as type "ID", including all topic and map element types, provide a declaration for theidElements
pattern. This is required to correctly configure the any pattern override in document-type shells and avoid errors from RELAX NG parsers. The declaration is specified with a@combine
attribute set to the value choice.For example:
<div> <a:documentation>LONG NAME: Map</a:documentation> <!-- ... --> <define name="idElements" combine="choice"> <ref name="map.element"/> </define> </div>
- Specialization attribute declarations
-
A vocabulary module must define a
@class
attribute for every specialized element. This is done in a section at the end of each module that includes atagname.attlist
pattern for each element type that is defined in the module. The declarations can occur in any order.The
tagname.attlist
pattern for each element defines the value for the@class
attribute for the element.@class
is declared as an optional attribute. The default value is declared using the@a:defaultValue
attribute, and the value of the attribute is constructed according to the rules in The class attribute rules and syntax.For example:<define name="topichead.attlist" combine="interleave"> <optional> <attribute name="class" a:defaultValue="+ map/topicref mapgroup-d/topichead " /> </optional> </define>
RELAX NG: Coding requirements for structural modules
This section is non-normative.
A structural vocabulary module defines a new topic or map type as a specialization of a topic or map type.
Required topic and map element attributes
The topic or map element type references the arch-atts
pattern, which
defines the @DITAArchVersion
attribute in the DITA architecture namespace
and sets the attribute to the version of DITA. In addition, the topic or map element type
references the specializations-att
pattern, which pulls in a definition for
the @specializations
attribute.
For example, the following definition references the arch-atts
and
specializations-att
patterns as part of the definition for the
<concept>
element.
<div>
<a:documentation> LONG NAME: Concept </a:documentation>
<!-- ... -->
<define name="concept.attlist" combine="interleave">
<ref name="concept.attributes"/>
<ref name="arch-atts"/>
<ref name="specializations-att"/>
</define>
<!-- ... -->
</div>
The @DITAArchVersion
and @specializations
attributes give
processors a reliable way to check the DITA version and the attribute domains that are
used.
Controlling nesting in topic types
A structural module that defines a new topic
type typically defines an info-types
style
pattern to specify a default for what topic types are permitted to
nest. Document-type shells then can control how topics are allowed
to nest by redefining the pattern.
The following rules apply when using a pattern to control topic nesting.
- Pattern name
-
The pattern name is the topic element name plus the suffix
-info-types
.For example, the info-types pattern for the concept topic type is
concept-info-types
. - Pattern value
-
To set up default topic-nesting rules, set the pattern to the desired topic elements. The default topic nesting is used when a document-type shell does not set up different rules.
For example:
<div> <a:documentation>INFO TYPES PATTERNS</a:documentation> <define name="mytopic-info-types"> <ref name="subtopictype-01.element"/> <ref name="subtopictype-02.element"/> </define> <!-- ... --> </div>
To disable topic nesting, specify the
<empty>
element.For example:
<define name="learningAssessment-info-types"> <empty/> </define>
The
info-types
pattern also can be used to refer to common nesting rules across the document-type shell.For example:
<div> <a:documentation>INFO TYPES PATTERNS</a:documentation> <define name="mytopic-info-types"> <ref name="info-types"/> </define> <!-- ... --> </div>
- Content model of the root element
-
In the declaration of the root element of a topic type, the last position in the content model is the
topictype-info-types
pattern.For example, the
<concept>
element places the pattern after<related-links>
:<div> <a:documentation>LONG NAME: Concept</a:documentation> <define name="concept.content"> <!-- ... --> <optional> <ref name="related-links"/> </optional> <zeroOrMore> <ref name="concept-info-types"/> </zeroOrMore> </define> </div>
In certain cases, you do not need to use the info-types
pattern to control
topic nesting:
- If a topic type will never permit topic nesting, regardless of context, it can be defined without any pattern or any nested topics.
- If a topic type will allow only specific nesting patterns, such as allowing only other topic types that are defined in the same module, it can nest those topics directly in the same way that other nested elements are defined.
RELAX NG: Coding requirements for element-domain modules
This section is non-normative.
Element-domain modules declare an extension pattern for each element that is extended by the domain. These patterns are used when including the domain module in document-type shells.
- Pattern name
-
The name of the pattern is the abbreviation for the domain, followed by a hyphen ("-"), and the name of the element that is extended.
Example
This section is non-normative.
For example, the name of the pattern for the highlighting domain that extends the
<ph>
element ishi-d-ph
. - Pattern definition
-
The pattern consists of a choice group that contains references to element-type name patterns. Each extension of the base element type is referenced.
Example
This section is non-normative.
The following code sample shows the pattern for the elements defined in the highlighting domain:
<a:documentation>DOMAIN EXTENSION PATTERNS</a:documentation> <define name="hi-d-ph"> <choice> <ref name="b.element"/> <ref name="i.element"/> <ref name="line-through.element"/> <ref name="overline.element"/> <ref name="sup.element"/> <ref name="sub.element"/> <ref name="tt.element"/> <ref name="u.element"/> </choice> </define>
- Extension pattern
-
For each element type that is extended by the element-domain module, the module extends the element-type pattern with a
@combine
value of choice that contains a reference to the domain pattern.Example
This section is non-normative.
For example, the following pattern adds the highlight domain specializations of the
<ph>
element to the content model of the<ph>
element:<define name="ph" combine="choice"> <ref name="hi-d-ph"/> </define>
Because the pattern uses a
@combine
value of choice, the effect is that the domain-provided elements automatically are added to the effective content model of the extended element in any grammar that includes the domain module.
RELAX NG: Coding requirements for attribute-domain modules
This section is non-normative.
An attribute-domain vocabulary module declares a new attribute specialized from either
the @props
or @base
attribute.
The name of an attribute domain is the name of the attribute
plus Att. For example, for the attribute named
@deliveryTarget
, the attribute-domain name is "deliveryTargetAtt". The
attribute-domain name is used to construct pattern names for the domain.
An attribute-domain module consists of a single file, which has three sections:
- Specializations attribute contribution
-
The contribution to the
@specializations
attribute is documented in the module. The value is constructed according to the rules found in The specializations 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 also can be used. - Attribute declaration pattern
-
The specialized attribute is declared in a pattern named
domainName-d-attribute
. The attribute is defined as optional.For example, the following code samples shows the the
@audience
specialization of@props
:<define name="audienceAtt-d-attribute"> <optional> <attribute name="audience" dita:since="2.0"> <a:documentation>Specifies the audience to which an element applies.</a:documentation> </attribute> </optional> </define>
- Attribute extension pattern
-
The attribute extension pattern extends either the
@props
or@base
attribute-list pattern to include the attribute specialization.- Specializations of
@props
-
The pattern is named
props-attribute-extensions
. The pattern specifies a@combine
value of interleave, and the content of the pattern is a reference to the specialized-attribute declaration pattern.For example:
<define name="props-attribute-extensions" combine="interleave"> <ref name="audienceAtt-d-attribute"/> </define>
- Specializations of
@base
-
The pattern is named
base-attribute-extensions
. The pattern specifies a@combine
value of interleave, and the content of the pattern is a reference to the specialized-attribute declaration pattern.For example:
<define name="base-attribute-extensions" combine="interleave"> <ref name="myBaseSpecializationAtt-d-attribute"/> </define>
- Specializations of
RELAX NG: Coding requirements for element-configuration modules
This section is non-normative.
An element-configuration module (constraint and expansion) redefines the content model or attribute list for one or more elements.
Implementation of element-configuration modules
Element-configuration modules are implemented by importing the element-configuration modules into a document-type shell in place of the vocabulary module that is redefined. The element-configuration module itself imports the base vocabulary module; within the import, the module redefines the patterns as needed to implement the constraint, expansion, or both.
- Constraint modules
-
For example, a constraint module that modifies the
<topic>
element imports the base module topicMod.rng. Within that import, it constrains thetopic.content
pattern:<div> <a:documentation>ATTRIBUTES AND CONTENT MODEL OVERRIDES</a:documentation> <include href="urn:pubid:oasis:names:tc:dita:rng:topicMod.rng:2.0"> <define name="topic.content"> <ref name="title"/> <ref name="shortdesc"/> <optional> <ref name="prolog"/> </optional> <optional> <ref name="body"/> </optional> </define> </include> </div>
- Expansion modules
-
For example, an expansion module that modifies the content model of
<section>
imports the base module topicMod.rng. Within that import, it expands thesection.content
pattern:<a:documentation>CONTENT MODEL AND ATTRIBUTE LIST OVERRIDES</a:documentation> <include href="urn:pubid:oasis:names:tc:dita:rng:topicMod.rng:2.0"> <define name="section.content"> <optional> <ref name="title"/> </optional> <optional> <ref name="sectionDesc"/> </optional> <zeroOrMore> <ref name="section.cnt"/> </zeroOrMore> </define> </include> </div>
Note that the specialized element
<sectionDesc>
must be declared in an element-domain module that also is integrated into the document-type shell.
Combining multiple element-configuration modules
Because the element-configuration module imports the module that it modifies, only one element-configuration module can be used per vocabulary module; otherwise the vocabulary module would be imported multiple times. If multiple element configurations are combined for a single vocabulary module, they need to be implemented in one of the following ways:
- Combined into a single element-configuration module
-
The element configurations 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>
- Chaining element-configuration modules
-
Element-configuration modules can be chained so that each element-configuration module imports another, until the final element-configuration module 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.