The specialization hierarchy of each DITA element is declared as the value of the class attribute. The class attribute provides a mapping from the current name of the element to its more general equivalents, but it also can provide a mapping from the current name to more specialized equivalents. All specialization-aware processing can be defined in terms of class attribute values.
The class attribute tells a processor what general classes of elements the current element belongs to. DITA scopes elements by module type (for example topic type, domain type, or map type) instead of document type, which lets document type developers combine multiple module types in a single document without complicating transformation logic.
The sequence of values in the class attribute is important because it tells processors which value is the most general and which is most specific. This sequence is what enables both specialization aware processing and generalization.
- An initial "-" or "+" character followed by one or more spaces. Use "-" for element types that are defined in structural vocabulary modules, and use "+" for element types that are defined in domain modules.
- A sequence of one or more tokens of the form
each taoken separated by one or more spaces, where modulename is the
short name of the vocabulary module and typename is the element type
name. Tokens are ordered left to right from most general to most specialized.
These tokens provide a mapping for every structural type or domain in the ancestry of the specialized element. The specialization hierarchy for a given element type must reflect any intermediate modules between the base type and the specialization type, even those in which no element renaming occurs.
- At least one trailing space character (" "). The trailing space ensures that string matches on the tokens can always include a leading and trailing space in order to reliably match full tokens.
When the class attribute is declared in an XML grammar, it MUST be declared with a default value. In order to support generalization round-tripping (generalizing specialized content into a generic form and then returning it to the specialized form) the default value MUST NOT be fixed. This allows a generalization process to overwrite the default values that are defined by a general document type with specialized values taken from the document being generalized.
A vocabulary module MUST NOT change the class attribute for elements that it does not specialize, but simply reuses by reference from more generic levels. For example, if task, bctask, and guitask use the p element without specializing it, they MUST NOT declare mappings for it.
Authors SHOULD NOT modify the class attribute.
Example: DTD declaration for class attribute for the step element
The following code sample lists the DTD declaration for the class attribute for the step element:
<!ATTLIST step class CDATA "- topic/li task/step ">
This indicates that the step element is specialized from the li element in a generic topic. It also indicates explicitly that the step element is available in a task topic; this enables round-trip migration between upper level and lower level types without the loss of information.
Example: Element with class attribute made explicit
The following code sample shows the value of the class attribute for the wintitle element:
<wintitle class="+ topic/keyword ui-d/wintitle ">A specialized keyword</wintitle>
The class attribute and its value is generally not surfaced in authored DITA topics, although it might be made explicit as part of a processing operation.
Example: class attribute with intermediate value
The following code sample shows the value of a class attribute for an element in the guitask module, which is specialized from task. The element is specialized from keyword in the base topic vocabulary, rather than from an element in the task module:
<windowname class="- topic/keyword task/keyword guitask/windowname ">...</windowname>
The intermediate values are necessary so that generalizing and specializing transformations can map the values simply and accurately. For example, if task/keyword was missing as a value, and a user decided to generalize this guitask up to a task topic, then the transformation would have to guess whether to map to keyword (appropriate if task is more general than guitask, which it is) or leave it as windowname (appropriate if task were more specialized, which it isn't). By always providing mappings for more general values, processors can then apply the simple rule that missing mappings must by default be to more specialized values than the one we are generalizing to, which means the last value in the list is appropriate. For example, when generalizing guitask to task, if a p element has no target value for task, we can safely assume that p does not specialize from task and should not be generalized.