DITA 1.3 proposed feature 13120 Vocabulary for Publishing Process Definitions

Provides a vocabulary for capturing the details of deliverable production processes in order to facilitate interchange of production processes, both within the same publishing system and among disparate publishing systems.

Date and version information

Original requirement

From the email referenced above:

Given that sets of keydefs can be used to define peer reference as-published locations, it follows that we should standardize, or at least define clear conventions for, capturing the information needed make these keydef sets work for this processing use, just as we have with DITAVAL and SubjectScheme for filtering.

I don't think it will be that hard to define an appropriate vocabulary and we can start testing such a vocabulary with the Open Toolkit and, hopefully, other DITA processors, as soon as we have something drafted.

Thus I would like to propose that we define for DITA 1.3 new vocabulary that supports the use of keydef sets in processing that results in deliverables with resolved peer cross references.

[...] a given deliverable instance is identified by its publication/publication specification pair, meaning that, for a given processor, a given publication processed with a given publication specification will always produce the same deliverable instance.

It also means that two deliverable instances for a given publication are distinguished by their publication specifications.

This is important because you need to have a well-defined and reliable way to communicate *which* deliverable you want when configuring the as-published result of a given peer cross reference.

By formally defining the notion of "publication specification" it follows that publication specifications are objects, which means they have identity, with means they must have identifiers, which means we can use their identifiers to clearly and concisely talk about them. The only open question is what form the identifier takes and what space of names it exists in--this is likely to be processor specific.

Use cases

The use case supported is ultimately the requirement to have a navigable link, such as a cross reference, from a point in one deliverable to a point another, separate, deliverable.

In order to support this use case, processors must be able to communicate between production process instances for different deliverables the data needed to produce correct cross-deliverable links. The minimum data items required are the same regardless of the processing implementation details.

See Technical requirements for details on the processing involved in cross-deliverable addressing.

Benefits

Address the following questions:
  • Who will benefit from this feature?

    Anyone who needs to produce deliverables with links to other deliverables.

    Implementors of tools will benefit from having a standard for communicating processing-specific information, removing the need to for each tool to invent such a mechanism for itself.

  • What is the expected benefit?

    This proposal standardizes something that would otherwise require non-standard solutions. By being a standard it enables interoperation of otherwise uncoordinated deliverable-producing processors.

  • How many people probably will make use of this feature? For example, everyone, many, or few.

    For content that is organized and published primarily as books or book-like things, rather than as monolithic Web sites or similar packages, there is almost always a requirement for cross-deliverable links. Because DITA through 1.2 has not had a standard way to do cross-deliverable links, users have largely avoided using them. But it seems likely that there is a large fraction of DITA users who would create cross-deliverable links if there was a standard and manageable way to author and produce them.

  • How much of a positive impact is expected for the users who will make use of the feature? For example, significant or minor.

    The impact for users that need it is imense as it makes the currently-impossible possible.

Costs

Outline the impact (time and effort) of the feature on the following groups:
  • Maintainers of the DTDs and XSDs

    Will need to define the new vocabulary modules.

  • Editors of the DITA specification:
    • How many new topics will be required?

      One or two new topics in the Architecture specification to discuss the general subject of cross-deliverable linking and multi-pass processing.

      One new reference topic for each new element type defined in this proposal, roughly 10-to-15 new reference topics.

    • How many existing topics will need to be edited?

      Probably necessary to edit one or two topics to reflect this new facility.

    • Will the feature require substantial changes to the information architecture of the DITA specification? If so, what?

      The feature does not change the DITA architecture in any way. It simply codifies a mechanism that takes advantage of existing DITA facilities (keys).

  • Vendors of tools: XML editors,component content management systems, processsors, etc.

    As for DITAVAL, vendors are not required to support this two-pass process or standard production specifications. However, processors that do want to enable the use of this process will almost certainly need to be updated or modified in order to produce intermediate as-published keydef sets. It is unlikely that any existing processor has been implemented so as to make generation of intermedaite as-published keydef sets either possible or easy, because it requires a level of record keeping that is not generally required for single-pass processes.

  • DITA community-at-large. Will this feature add to the perception that DITA is becoming too complex? Will it be simple for end users to understand?

    This feature should not add to the perception of increased complexity as it enables an otherwise impossible feature, cross-deliverable addressing. Anyone who currently has a cross-deliverable addressing requirement either has already done something at least as complex (but non-standard) or understands the requirements and implementation challenges but has chosen not to implement support for it. Users that do not have such a requirement do not need to be aware of this feature.

Technical requirements

Terminology

publication
the thing to be delivered as represented by a root DITA map.
deliverable
The result of processing a publication to produce an output reflecting a unique set of input parameters including the deliverable data type (HTML, PDF, EPUB, etc.), the filtering specs (DITAVAL files), the delivered location (e.g., URL of where the deliverable will be published), and any other process-specific parameters what would result in a different deliverable (in particular, parameters that determine processor behavior where the DITA spec allows different behaviors, such as filtering before or after conref resolution).
deliverable definition
The set of parameters used to produce a deliverable.
as-published key definition set
A set of key definitions reflecting the key names as used by a specific publication and the locations of the referenced resources as published in a specific deliverable. These key definition sets are used in the processing of the referencing publication to produce the final deliverable with correct peer resource references.

Abstract Production Process

In general, a DITA root map can be processed to produce some form of deliverable. For the purposes of this proposal a deliverable is an artifact that reflects the structure and content of the root map and is intended for delivery to and consumption by some agent, such as a human reader. This proposal is only interested in deliverables that will be published (made available) in such a way that there may be navigable hyperlinks from one deliverable to another, that is, cross-deliverable links.

When maps are published in isolation, without regard to cross-deliverable links, then the production process can be a single pass such that the immediate output of the production process is the final deliverable.

However, when there may be cross-deliverable links, the production process must necessarily be a two-pass process in order to resolve reflexive dependencies among the deliverables involved. That is, if deliverable A links to deliverable B and deliverable B links to deliverable A, both A and B must be produced once, producing mappings of the addresses in A and B as authored to those same things in A and B as delivered. Those mappings are then inputs to the second-pass processing of maps A and B, with B's mapping being an input to A's second pass and A's mapping an input to B's second pass. (And in fact, more than two passes may be required if the result of using deliverable-specific addresses in the second pass would change the addressing details in the deliverable, for example, changing the page numbers on which a given potential target element fell. However, for deliverables where addressing is by some form of ID not dependent on things like pagination, two passes should always be sufficient.)

The details of the processing are of course processor specific, but the general algorithm for the two-pass process is independent of implementation details. In particular, the processing can be defined entirely in terms of simple one-pass processes plus manual manipulation of the original input maps between pass one and pass two. Of course, processing tools would likely automate these intermediate steps, but such automation is not a prerequisite for applying this process.

Also, note that per proposal 13041, Cross-deliverable Linking, from a given root map, you know which other root maps it has links to. This means that the two-pass process can be fully automated when the business rules for selecting the target deliverables to use are also automatable (for example, "like links to like"). It is automatable because the system knows which key references are to peer maps and therefore can replace those key references with the appropriate as-delivered maps for the target deliverables produced from those peer maps in the intermediate maps produced out of pass 1, as described below.

Another challenge with cross-deliverable addressing is key-based addressing of elements within topics. Because keys can only address topics, key-based references to elements within topics always consist of a key/element-id pair specified at the point of reference. This means that in the DITA content as authored, there is not a single indirector for each element referenced, there is only the indirector to the containing topic. For example, consider the case where a topic has two addressible elements, "fig-01" and "fig-02" and that topic is bound to the key "topic-02". The key definition will be:
<map>
  ...
  <keydef keys="topic-02"
       href="topics/topic-02.dita"
  />
  ...
  <topicref href="topics/topic-01.dita"/>
  <topicref href="topics/topic-02.dita"/>
</map>
Within topic 2 there are then two cross references, one to each figure:
<topic id="topic-02">
  <title>Topic Two</title>
  <body>
   <p>See <xref keyref="topic-02/fig-01"/> ...</p>
   <p>See <xref keyref="topic-02/fig-02"/> ...</p>
  </body>
</topic>

In the as-delivered key definition set, each figure needs to have its own key because there must be a separate URI for each thing to be addressed in the deliverable. Thus both the generated keys and the references to them will be different from the source as authored.

The as-delivered keys will be something like:
<deliverableAsDeliveredKeydefSet>
  ...
  <keydef keys="topic-02"
       href="http://example.com/pubs/map-b/topics/topic-02.html"
       format="html"
       scope="external"
  />
  <keydef keys="topic-02_fig-01"
       href="http://example.com/pubs/topics/topic-02.html#fig-01"
       format="html"
       scope="external"
  />
  <keydef keys="topic-02_fig-02"
       href="http://example.com/pubs/topics/topic-02.html#fig-02"
       format="html"
       scope="external"
  />
</deliverableAsDeliveredKeydefSet>
Likewise, the copy of topic 2 generated out of pass 1 must reflect these new keys:
<topic id="topic-02">
  <title>Topic Two</title>
  <body>
   <p>See <xref keyref="topic-02_fig-01"/> ...</p>
   <p>See <xref keyref="topic-02_fig-02"/> ...</p>
  </body>
</topic>

Note that now the @keyref values are just key references, not key/element-id pairs.

The implication of this is that the as-delivered key definition set must include a key definition for each element within a topic when the topic is also bound to a key (topics for which there is no key binding cannot be addressed across deliverables and thus their elements are not relevant for cross-deliverable addressing). Because in the general case you cannot predict what other documents may want to link to what addressible elements in the document you are producing, the only option is to generate key bindings for all of them. In the case where a processor is processing a set of interrelated documents together as a unit it can optimize the key definition set by determining the set of things that are actually addressed from other documents and generating only the key definitions that are required.

The two pass production process can be summarized as:
  1. Pass 1: The initial root map is processed to produce a specific deliverable, as described by a deliverable definition. The deliverable definition must include the following information:
    • The deliverable details, which must include the data type of the deliverable (HTML, PDF, EPUB, etc.)
    • Any DITAVAL specifications.
    • Any processor-specific parameters that could affect the details of the deliverable in a way that would affect addressing of the deliverable.

    Note that a root map/deliverable definition pair uniquely identifies a deliverable instance.

    The output of pass one includes the following artifacts:
    • An as-delivered key definition set that reflects for each key defined in the original input map and each element with an ID in each topic to which a key is bound, the location of the referenced resource in the deliverable produced. Each key in the definition set has a @scope of "external" and a @format value reflecting the data type of the deliverable, e.g. "html", "pdf", etc., e.g. The @href value reflects the location of the deliverable, usually (but not necessarily) as an absolute URL:
          <keydef keys="key-01" 
            href="http://example.com/foo/bar.html" 
            format="html" 
            scope="external"
          />
      
    • A copy of the original input map to be used as the input to pass 2 in place of the original input map. This copy of the map can reflect any merging of sub maps or propagation of attributes performed in the first pass, as the processing parameters that could affect the details of the merged map and propagated attributes will not change between pass 1 and pass 2.
    • A copy of each topic where each key reference is rewritten as necessary to replace key/element-id pairs with single keys bound to direct URI references to the target element as delivered.

    Note that it is not necessary actually produce the deliverable in pass 1, it is only necessary to determine what the location as delivered for each key is. That determination may require actually generating the deliverable or it may be the application of a simple algorithm, depending on the nature of the deliverable format and the business rules for generating addresses in the result deliverable.

  2. For each root map to which the initial root map links, all required deliverables are produced and the as-delivered key definitions for each map are made available to the person or automated system managing the processing of the initial root map. Note that different processing systems may process the other maps. The only thing that is interchanged is the as-delivered key definition sets, one for each unique deliverable (map/deliverable definition pair). Note also that this requires that the agent managing the production of the initial root map know which deliverable forms of each target map it needs or may need. This could be the result of a decision made at production time or it could be the result of a business rule, such as "we always produce HTML, PDF, and EPUB for each publication".
  3. The agent managing the processing of the initial map decides, for each target peer map, which deliverables it needs to link to and then chooses or edits as necessary the peer map's as-delivered keydef sets until they have a set of keys that reflects their required links from the deliverable for the initial root map to the deliverables for the target peer map.

    This editing process can be as simple as replacing the original peer map reference with a reference to the key definition set for a specific deliverable or it can involve manual combination of key definitions from different deliverable sets, including adding key scopes to enable simultaneous linking to different deliverable forms of the same target root map.

    In practice, it is expected that this manipulation of key definition sets would either be entirely automatic (e.g., HTML always links to HTML, PDF always links to PDF, etc.) or assisted in some way by tools. However, the process can be performed by unaided authors editing normal maps containing sets of key definitions, however tedious that process might be.

    Note that every target peer root map will be represented by one or more peer-scope key definitions per proposal 13041. Those key definitions are easy to find because they have a scope value of "peer", name a key scope, and have a format of "ditamap". Those keys serve as a manifest of the key definitions that need to be replaced with references to as-delivered key definition sets.

  4. Pass 2: Process the map copy prepared in step 3 of Pass 1 to produce the final deliverable for the original input map.

Each as-delivered key definition set should reflect the deliverable it reflects, that is the root map/deliverable definition pair that resulted from it. Thus there should be standard metadata in the key definition set that contains that information, making the key definition set discoverable regardless of what processing system produced it.

Markup Design

The markup design consists to three modules:
  • A deliverable definition metadata domain that provides elements for capturing all the relevant details about a deliverable production process or a deliverable instance.
  • A specialized deliverable-definition topic type used to represent deliverable definitions. It uses the deliverable details metadata domain for all deliverable-specific metadata.
  • A deliverable as-delivered key definition set map type that integrates the deliverable metadata domain.
Figure 1. Deliverable metadata domain declarations (RelaxNG)
<?xml version="1.0" encoding="UTF-8"?>
<!-- ============================================================= 
     MODULE:    DITA Deliverable Metadata Domain - RNG              
     VERSION:   1.3                                           
     DATE:      October 2013                                       
     ============================================================= -->
<!--
     Refer to the latest version of this file by the following URI:
     urn:oasis:names:tc:dita:rng:deliverableMetadataDomainMod
     To refer to this specific version, you may use this value:
     urn:oasis:names:tc:dita:rng:deliverableMetadataDomainMod:1.3
-->
<grammar xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" 
  xmlns="http://relaxng.org/ns/structure/1.0">
  
  <!-- Define the domain values of this module -->
  <define name="domains-atts-value" combine="choice">
    <value>(topic deliveryMetadata-d)</value>
  </define>
  
  <!-- Define domain extension patterns -->
  <define name="deliveryMetadata-d-data">
    <choice>
      <ref name="deliverableInstanceMetadata.element"/>
    </choice>
  </define>
  <!-- Extend the patterns with the domain contribution -->
  <define name="data" combine="choice">
    <ref name="deliveryMetadata-d-data"/>
  </define>
  
  <define name="deliverableInstanceMetadata">
    <ref name="deliverableInstanceMetadata.element"/>
  </define>
  <define name="rootMap">
    <ref name="rootMap.element"/>
  </define>
  <define name="finalDeliveryLocation">
    <ref name="finalDeliveryLocation.element"/>
  </define>
  <define name="deliverableProcessMetadata">
    <ref name="deliverableProcessMetadata.element"/>
  </define>
  <define name="transformType">
    <ref name="transformType.element"/>
  </define>
  <define name="deliverableDatatype">
    <ref name="deliverableDatatype.element"/>
  </define>
  <define name="ditavals">
    <ref name="ditavals.element"/>
  </define>
  <define name="ditavalref">
    <ref name="ditavalref.element"/>
  </define>
  <define name="processParameters">
    <ref name="processParameters.element"/>
  </define>
  <define name="processParam">
    <ref name="processParam.element"/>
  </define>
  
  <!-- Define elements content and attributes -->
  
  <!-- 
    <deliverableInstanceMetadata class="+ topic/data " >
      <rootMap  class="+ topic/data " >file://home/user/maps/map-a.ditamap</rootMap>
      <finalDeliveryLocation class="+ topic/data " >http://example.com/publications/pub-a/index.html</finalDeliveryLocation>
    </deliverableInstanceMetadata>

  -->
  
  <!-- LONG NAME: Deliverable instance metadata -->
  <define name="deliverableInstanceMetadata.content">
    <group>
      <ref name="rootMap"/>
      <ref name="finalDeliveryLocation"/>
    </group>
  </define>
  <define name="deliverableInstanceMetadata.attributes">
    <ref name="univ-atts"/>
    <optional>
      <attribute name="outputclass"/>
    </optional>
  </define>
  <define name="deliverableInstanceMetadata.element">
    <element name="deliverableInstanceMetadata">
      <a:documentation>Contains the metadata describing an instance of a deliverable for a 
      specific root map.</a:documentation>
      <ref name="deliverableInstanceMetadata.attlist"/>
      <ref name="deliverableInstanceMetadata.content"/>
    </element>
  </define>
  <define name="deliverableInstanceMetadata.attlist" combine="interleave">
    <ref name="deliverableInstanceMetadata.attributes"/>
  </define>
  
  <!-- LONG NAME: Root Map -->
  <define name="rootMap.content">
    <choice>
      <text/>
    </choice>
  </define>
  <define name="rootMap.attributes">
    <ref name="univ-atts"/>
    <optional>
      <attribute name="outputclass"/>
    </optional>
  </define>
  <define name="rootMap.element">
    <element name="rootMap">
      <a:documentation>Specifies the URI of the root map from which the deliverable was produced.</a:documentation>
      <ref name="rootMap.attlist"/>
      <ref name="rootMap.content"/>
    </element>
  </define>
  <define name="rootMap.attlist" combine="interleave">
    <ref name="rootMap.attributes"/>
  </define>
  
  <!-- LONG NAME: Final Delivery Location -->
  <define name="finalDeliveryLocation.content">
    <choice>
      <text/>
    </choice>
  </define>
  <define name="finalDeliveryLocation.attributes">
    <ref name="univ-atts"/>
    <optional>
      <attribute name="outputclass"/>
    </optional>
  </define>
  <define name="finalDeliveryLocation.element">
    <element name="finalDeliveryLocation">
      <a:documentation>Specifies the URI of the location where the deliverable will be published.</a:documentation>
      <ref name="finalDeliveryLocation.attlist"/>
      <ref name="finalDeliveryLocation.content"/>
    </element>
  </define>
  <define name="finalDeliveryLocation.attlist" combine="interleave">
    <ref name="finalDeliveryLocation.attributes"/>
  </define>
  
  <!-- LONG NAME: Deliverable Process Metadata -->
  <define name="deliverableProcessMetadata.content">
    <group>
      <ref name="transformType"/>
      <ref name="deliverableDatatype"/>
      <choice>
        <ref name="ditavals"/>
      </choice>
      <choice>
        <ref name="processParameters"/>
      </choice>
    </group>
  </define>
  <define name="deliverableProcessMetadata.attributes">
    <ref name="univ-atts"/>
    <optional>
      <attribute name="outputclass"/>
    </optional>
  </define>
  <define name="deliverableProcessMetadata.element">
    <element name="deliverableProcessMetadata">
      <a:documentation>Defines a deliverable process.</a:documentation>
      <ref name="deliverableProcessMetadata.attlist"/>
      <ref name="deliverableProcessMetadata.content"/>
    </element>
  </define>
  <define name="deliverableProcessMetadata.attlist" combine="interleave">
    <ref name="deliverableProcessMetadata.attributes"/>
  </define>
  
  <!-- LONG NAME: transformType -->
  <define name="transformType.content">
    <choice>
      <text/>
    </choice>
  </define>
  <define name="transformType.attributes">
    <ref name="univ-atts"/>
    <optional>
      <attribute name="outputclass"/>
    </optional>
  </define>
  <define name="transformType.element">
    <element name="transformType">
      <a:documentation>The "transformation type", as for the DITA Open Toolkit.
      More generally, the transformation type represents a class of processes
      that produce a specific type of output, such as HTML, PDF, EPUB, etc.
      The exact meaning of transformation type names is processor-specific.</a:documentation>
      <ref name="transformType.attlist"/>
      <ref name="transformType.content"/>
    </element>
  </define>
  <define name="transformType.attlist" combine="interleave">
    <ref name="transformType.attributes"/>
  </define>
  
  <!-- LONG NAME: Deliverable Datatype -->
  <define name="deliverableDatatype.content">
    <choice>
      <text/>
    </choice>
  </define>
  <define name="deliverableDatatype.attributes">
    <ref name="univ-atts"/>
    <optional>
      <attribute name="outputclass"/>
    </optional>
  </define>
  <define name="deliverableDatatype.element">
    <element name="deliverableDatatype">
      <a:documentation>The datatype of the deliverable produced, such as
      "HTML", "XHTML", "PDF", "EPUB2", "EPUB3", etc. The same transformation
      type may result in different deliverable datatypes.</a:documentation>
      <ref name="deliverableDatatype.attlist"/>
      <ref name="deliverableDatatype.content"/>
    </element>
  </define>
  <define name="deliverableDatatype.attlist" combine="interleave">
    <ref name="deliverableDatatype.attributes"/>
  </define>
  
  <!-- LONG NAME: ditavals -->
  <define name="ditavals.content">
    <zeroOrMore>
      <choice>
        <ref name="ditavalref"/>
      </choice>
    </zeroOrMore>
  </define>
  <define name="ditavals.attributes">
    <ref name="univ-atts"/>
    <optional>
      <attribute name="outputclass"/>
    </optional>
  </define>
  <define name="ditavals.element">
    <element name="ditavals">
      <a:documentation>Contains references to the DITAVAL specifications
      used as input to the deliverable production process.</a:documentation>
      <ref name="ditavals.attlist"/>
      <ref name="ditavals.content"/>
    </element>
  </define>
  <define name="ditavals.attlist" combine="interleave">
    <ref name="ditavals.attributes"/>
  </define>
  
  <!-- LONG NAME: ditavalref -->
  <define name="ditavalref.content">
    <choice>
      <text/>
    </choice>
  </define>
  <define name="ditavalref.attributes">
    <ref name="univ-atts"/>
    <optional>
      <attribute name="outputclass"/>
    </optional>
  </define>
  <define name="ditavalref.element">
    <element name="ditavalref">
      <a:documentation>The URI of a DITAVAL document.</a:documentation>
      <ref name="ditavalref.attlist"/>
      <ref name="ditavalref.content"/>
    </element>
  </define>
  <define name="ditavalref.attlist" combine="interleave">
    <ref name="ditavalref.attributes"/>
  </define>
  
  <!-- LONG NAME: processParameters -->
  <define name="processParameters.content">
    <zeroOrMore>
      <choice>
        <ref name="processParam"/>
      </choice>
    </zeroOrMore>
  </define>
  <define name="processParameters.attributes">
    <ref name="univ-atts"/>
    <optional>
      <attribute name="outputclass"/>
    </optional>
  </define>
  <define name="processParameters.element">
    <element name="processParameters">
      <a:documentation>Contains references to the DITAVAL specifications
        used as input to the deliverable production process.</a:documentation>
      <ref name="processParameters.attlist"/>
      <ref name="processParameters.content"/>
    </element>
  </define>
  <define name="processParameters.attlist" combine="interleave">
    <ref name="processParameters.attributes"/>
  </define>
  
  <!-- LONG NAME: processParam -->
  <define name="processParam.content">
    <choice>
      <text/>
    </choice>
  </define>
  <define name="processParam.attributes">
    <attribute name="name"/>
    <attribute name="value"/>
    <ref name="univ-atts"/>    
    <optional>
      <attribute name="outputclass"/>
    </optional>
  </define>
  <define name="processParam.element">
    <element name="processParam">
      <a:documentation>Represents a parameter to the production process. The @name attribute
      specifies the parameter name, the @value attribute specifies the parameter value.</a:documentation>
      <ref name="processParam.attlist"/>
      <ref name="processParam.content"/>
    </element>
  </define>
  <define name="processParam.attlist" combine="interleave">
    <ref name="processParam.attributes"/>
  </define>
  
  <!--  
  <deliverableProcessMetadata>
    <transformType>html</transformType>
    <deliverableDatatype>HTML</deliverableDatatype>
    <ditavals>
      <ditavalref>file://home/user/ditavals/ditaval-01.ditaval</ditavalref>
      <ditavalref>file://home/user/ditavals/ditaval-02.ditaval</ditavalref>
    </ditavals>
    <processParameters>
      <processParam name="param1" value="value1"/>
      <processParam name="param2" value="value2"/>
    </processParameters>
  </deliverableProcessMetadata>    
  
-->  
  
  <!-- Specialization attributes. Global attributes and class defaults -->

  <define name="deliverableInstanceMetadata.attlist" combine="interleave">
    <ref name="global-atts"/>
    <optional>
      <attribute name="class" a:defaultValue="+ topic/data deliverableMetadata-d/deliverableInstanceMetadata "/>
    </optional>
  </define>
  <define name="rootMap.attlist" combine="interleave">
    <ref name="global-atts"/>
    <optional>
      <attribute name="class" a:defaultValue="+ topic/data deliverableMetadata-d/rootMap "/>
    </optional>
  </define>
  <define name="finalDeliveryLocation.attlist" combine="interleave">
    <ref name="global-atts"/>
    <optional>
      <attribute name="class" a:defaultValue="+ topic/data deliverableMetadata-d/finalDeliveryLocation "/>
    </optional>
  </define>
  <define name="deliverableProcessMetadata.attlist" combine="interleave">
    <ref name="global-atts"/>
    <optional>
      <attribute name="class" a:defaultValue="+ topic/data deliverableMetadata-d/deliverableProcessMetadata "/>
    </optional>
  </define>
  <define name="transformType.attlist" combine="interleave">
    <ref name="global-atts"/>
    <optional>
      <attribute name="class" a:defaultValue="+ topic/data deliverableMetadata-d/transformType "/>
    </optional>
  </define>
  <define name="deliverableDatatype.attlist" combine="interleave">
    <ref name="global-atts"/>
    <optional>
      <attribute name="class" a:defaultValue="+ topic/data deliverableMetadata-d/deliverableDatatype "/>
    </optional>
  </define>
  <define name="ditavals.attlist" combine="interleave">
    <ref name="global-atts"/>
    <optional>
      <attribute name="class" a:defaultValue="+ topic/data deliverableMetadata-d/ditavals "/>
    </optional>
  </define>
  <define name="ditavalref.attlist" combine="interleave">
    <ref name="global-atts"/>
    <optional>
      <attribute name="class" a:defaultValue="+ topic/data deliverableMetadata-d/ditavalref "/>
    </optional>
  </define>
  <define name="processParameters.attlist" combine="interleave">
    <ref name="global-atts"/>
    <optional>
      <attribute name="class" a:defaultValue="+ topic/data deliverableMetadata-d/processParameters "/>
    </optional>
  </define>
  <define name="processParam.attlist" combine="interleave">
    <ref name="global-atts"/>
    <optional>
      <attribute name="class" a:defaultValue="+ topic/data deliverableMetadata-d/processParam "/>
    </optional>
  </define>
</grammar>
Figure 2. Deliverable definition topic type (RelaxNG)
<?xml version="1.0" encoding="UTF-8"?>
<!-- ============================================================= 
  MODULE:    DITA Deliverable Definition - RNG              
  VERSION:   1.3                                                
  DATE:      June 2013                                       
  ============================================================= -->
<!--
  Refer to the latest version of this file by the following URI:
  urn:oasis:names:tc:dita:rng:deliverableDefinition.mod.rng
  To refer to this specific version, you may use this value:
  urn:oasis:names:tc:dita:deliverableDefinition.mod.rng:1.3
-->
<grammar xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" 
  xmlns="http://relaxng.org/ns/structure/1.0" 
  datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
  <!-- Define the domain values of this module -->
  <define name="domains-atts-value" combine="choice">
    <value>(topic deliverableDefinition)</value>
  </define>
  
  <!-- Topic nesting -->
  <define name="deliverableDefinition-info-types">
    <notAllowed/>
  </define>
  
  <!-- Define patterns -->
  <define name="deliverableDefinition">
    <ref name="deliverableDefinition.element"/>
  </define>
  <define name="deliverableDefinitionBody">
    <ref name="deliverableDefinitionBody.element"/>
  </define>
  
  <!-- Define elements content and attributes -->
  
  <!-- LONG NAME: Concept -->
  <define name="deliverableDefinition.content">
    <ref name="title"/>
    <optional>
      <ref name="titlealts"/>
    </optional>
    <optional>
      <choice>
        <ref name="abstract"/>
        <ref name="shortdesc"/>
      </choice>
    </optional>
    <optional>
      <ref name="prolog"/>
    </optional>
    <optional>
      <ref name="deliverableDefinitionBody"/>
    </optional>
    <optional>
      <ref name="related-links"/>
    </optional>
    <zeroOrMore>
      <ref name="deliverableDefinition-info-types"/>
    </zeroOrMore>
  </define>
  <define name="deliverableDefinition.attributes">
    <attribute name="id">
      <data type="ID"/>
    </attribute>
    <ref name="conref-atts"/>
    <ref name="select-atts"/>
    <ref name="localization-atts"/>
    <optional>
      <attribute name="outputclass"/>
    </optional>
  </define>
  <define name="deliverableDefinition.element">
    <element name="deliverableDefinition">
      <a:documentation>The &lt;deliverableDefinition> element is the top-level element for a topic that answers
        the question what is? Concepts provide background information that users must know before
        they can successfully work with a product or interface. Often, a deliverableDefinition is an extended
        definition of a major abstraction such as a process or function. It might also have an
        example or a graphic, but generally the structure of a deliverableDefinition is fairly simple. 
        Category: Concept elements</a:documentation>
      <ref name="deliverableDefinition.attlist"/>
      <ref name="deliverableDefinition.content"/>
    </element>
  </define>
  <define name="deliverableDefinition.attlist" combine="interleave">
    <ref name="deliverableDefinition.attributes"/>
    <ref name="arch-atts"/>
    <ref name="domains-atts"/>
  </define>
  
  <!-- LONG NAME: Deliverable Definition Body Body -->
  <define name="deliverableDefinitionBody.content">
    <choice>
      <ref name="deliverableProcessMetadata"/>
    </choice>
    <zeroOrMore>
      <ref name="body.cnt"/>
    </zeroOrMore>
  </define>
  <define name="deliverableDefinitionBody.attributes">
    <ref name="id-atts"/>
    <ref name="localization-atts"/>
    <optional>
      <attribute name="base"/>
    </optional>
    <ref name="base-attribute-extensions"/>
    <optional>
      <attribute name="outputclass"/>
    </optional>
  </define>
  <define name="deliverableDefinitionBody.element">
    <element name="deliverableDefinitionBody">
      <a:documentation>The &lt;deliverableDefinitionBody> element is the main body-level element for a deliverableDefinition. Contains the deliverable definition metadata, optionally followed by
      any normal topic body content.</a:documentation>
      <ref name="deliverableDefinitionBody.attlist"/>
      <ref name="deliverableDefinitionBody.content"/>
    </element>
  </define>
  <define name="deliverableDefinitionBody.attlist" combine="interleave">
    <ref name="deliverableDefinitionBody.attributes"/>
  </define>
  

  <!-- Specialization attributes. Global attributes and class defaults -->

  <define name="deliverableDefinition.attlist" combine="interleave">
    <ref name="global-atts"/>
    <optional>
      <attribute name="class" a:defaultValue="- topic/topic deliverableDefinition/deliverableDefinition "/>
    </optional>
  </define>
  <define name="deliverableDefinitionBody.attlist" combine="interleave">
    <ref name="global-atts"/>
    <optional>
      <attribute name="class" a:defaultValue="- topic/body  deliverableDefinition/deliverableDefinitionBody "/>
    </optional>
  </define>
</grammar>
Figure 3. Deliverable as-delivered key definition set declarations (RelaxNG)
<?xml version="1.0" encoding="UTF-8"?>
<!-- ============================================================= 
     MODULE:    DITA Deliverable As-Delivered Key Definition Set - RNG              
     VERSION:   1.3                                           
     DATE:      June 2013                                       
     ============================================================= -->
<!--
     Refer to the latest version of this file by the following URI:
     urn:oasis:names:tc:dita:rng:deliverableAsDeliveredKeydefSetMod
     To refer to this specific version, you may use this value:
     urn:oasis:names:tc:dita:rng:deliverableAsDeliveredKeydefSetMod:1.3
-->
<grammar xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" 
  xmlns="http://relaxng.org/ns/structure/1.0"
  datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
  >
  
  <!-- Define the domain values of this module -->
  <define name="domains-atts-value" combine="choice">
    <value>(map deliverableAsDeliveredKeydefSet deliveryMetadata-d)</value>
  </define>
  
  <!-- Define patterns -->
  <define name="deliverableAsDeliveredKeydefSet">
    <ref name="deliverableAsDeliveredKeydefSet.element"/>
  </define>
  <define name="deliverableKeydefsetMetadata">
    <ref name="deliverableKeydefsetMetadata.element"/>
  </define>
  
  
  <!-- LONG NAME: Deliverable-As-Delivered Key Definition Set -->
  <define name="deliverableAsDeliveredKeydefSet.content">
    <optional>
      <ref name="title"/>
    </optional>
    <optional>
      <ref name="deliverableKeydefsetMetadata"/>
    </optional>
    <zeroOrMore>
      <choice>
        <ref name="data.elements.incl"/>
        <ref name="topicref"/>
      </choice>
    </zeroOrMore>
  </define>
  <define name="deliverableAsDeliveredKeydefSet.attributes">
    <optional>
      <attribute name="title"/>
    </optional>
    <optional>
      <attribute name="id">
        <data type="ID"/>
      </attribute>
    </optional>
    <ref name="conref-atts"/>
    <optional>
      <attribute name="anchorref"/>
    </optional>
    <optional>
      <attribute name="outputclass"/>
    </optional>
    <ref name="localization-atts"/>
    <ref name="topicref-atts"/>
    <ref name="select-atts"/>
  </define>
  <define name="deliverableAsDeliveredKeydefSet.element">
    <a:documentation>The &lt;map> element is used to define a map which describes the relationships
      among a set of resources, such as DITA topics. Maps consist of references to topics and other
      resources organized into hierarchies, groups, and tables. Maps provide a way to express these
      relationships in a single common format that can be used for different outputs. 
      Category: Map elements</a:documentation>
    <element name="deliverableAsDeliveredKeydefSet">
      <ref name="deliverableAsDeliveredKeydefSet.attlist"/>
      <ref name="deliverableAsDeliveredKeydefSet.content"/>
    </element>
  </define>
  <define name="deliverableAsDeliveredKeydefSet.attlist" combine="interleave">
    <ref name="deliverableAsDeliveredKeydefSet.attributes"/>
    <ref name="arch-atts"/>
    <ref name="domains-atts"/>
  </define>
  
  <!-- LONG NAME: deliverableKeydefsetMetadata -->
  <define name="deliverableKeydefsetMetadata.content">
    <optional>
      <ref name="navtitle"/>
    </optional>
    <optional>
      <ref name="searchtitle"/>
    </optional>
    <optional>
      <ref name="shortdesc"/>
    </optional>
    <zeroOrMore>
      <ref name="author"/>
    </zeroOrMore>
    <optional>
      <ref name="source"/>
    </optional>
    <optional>
      <ref name="publisher"/>
    </optional>
    <zeroOrMore>
      <ref name="copyright"/>
    </zeroOrMore>
    <optional>
      <ref name="critdates"/>
    </optional>
    <optional>
      <ref name="permissions"/>
    </optional>
    <zeroOrMore>
      <ref name="metadata"/>
    </zeroOrMore>
    <zeroOrMore>
      <ref name="audience"/>
    </zeroOrMore>
    <zeroOrMore>
      <ref name="category"/>
    </zeroOrMore>
    <zeroOrMore>
      <ref name="keywords"/>
    </zeroOrMore>
    <zeroOrMore>
      <ref name="prodinfo"/>
    </zeroOrMore>
    <zeroOrMore>
      <ref name="othermeta"/>
    </zeroOrMore>
    <zeroOrMore>
      <ref name="resourceid"/>
    </zeroOrMore>
    <ref name="deliverableInstanceMetadata"/>
    <ref name="deliverableProcessMetadata"/>
    <zeroOrMore>
      <choice>
        <ref name="data.elements.incl"/>
        <ref name="foreign.unknown.incl"/>
      </choice>
    </zeroOrMore>
  </define>
  <define name="deliverableKeydefsetMetadata.attributes">
    <optional>
      <attribute name="lockmeta">
        <choice>
          <value>no</value>
          <value>yes</value>
          <value>-dita-use-conref-target</value>
        </choice>
      </attribute>
    </optional>
    <ref name="univ-atts"/>
  </define>
  <define name="deliverableKeydefsetMetadata.element">
    <a:documentation>Holds the metadata that describes the deliverable instance this key definition set reflects.</a:documentation>
    <element name="deliverableKeydefsetMetadata">
      <ref name="deliverableKeydefsetMetadata.attlist"/>
      <ref name="deliverableKeydefsetMetadata.content"/>
    </element>
  </define>
  <define name="deliverableKeydefsetMetadata.attlist" combine="interleave">
    <ref name="deliverableKeydefsetMetadata.attributes"/>
  </define>
  
  <!-- Specialization attributes. Global attributes and class defaults -->

  <define name="deliverableAsDeliveredKeydefSet.attlist" combine="interleave">
    <ref name="global-atts"/>
    <optional>
      <attribute name="class" a:defaultValue="+ map/map deliverableAsDeliveredKeydefSet/deliverableAsDeliveredKeydefSet "/>
    </optional>
  </define>
  <define name="deliverableKeydefsetMetadata.attlist" combine="interleave">
    <ref name="global-atts"/>
    <optional>
      <attribute name="class" a:defaultValue="- map/topicmeta  deliverableAsDeliveredKeydefSet/deliverableKeydefsetMetadata "/>
    </optional>
  </define>
</grammar>

Examples

Figure 4. Sample deliverable definition
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="../doctypes/rng/deliverableDefinition.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<deliverableDefinition id="deliverable-def">
  <title>Deliverable Definition XYZ</title>
  <shortdesc>Parameters for HTML output filtered for ...</shortdesc>
  <deliverableDefinitionBody>    
    <deliverableProcessMetadata>
      <transformType>html</transformType>
      <deliverableDatatype>HTML</deliverableDatatype>
      <ditavals>
        <ditavalref>file://home/user/ditavals/ditaval-01.ditaval</ditavalref>
        <ditavalref>file://home/user/ditavals/ditaval-02.ditaval</ditavalref>
      </ditavals>
      <processParameters>
        <processParam name="param1" value="value1"/>
        <processParam name="param2" value="value2"/>
      </processParameters>
    </deliverableProcessMetadata>    
    <p>Whatever additional information you want here.</p>
  </deliverableDefinitionBody>
</deliverableDefinition>
Figure 5. Sample as-delivered key definition set
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="../doctypes/rng/deliverableAsDeliveredKeydefSet.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<deliverableAsDeliveredKeydefSet>
  <title>Publication Map A As-Delivered Keydef set for Deliverable XYZ</title>
  <deliverableKeydefsetMetadata>
    <deliverableInstanceMetadata>
      <rootMap>file://home/user/maps/map-a.ditamap</rootMap>
      <finalDeliveryLocation>http://example.com/publications/pub-a/index.html</finalDeliveryLocation>
    </deliverableInstanceMetadata>
    <deliverableProcessMetadata>
      <transformType>html</transformType>
      <deliverableDatatype>HTML</deliverableDatatype>
      <ditavals>
        <ditavalref>file://home/user/ditavals/ditaval-01.ditaval</ditavalref>
        <ditavalref>file://home/user/ditavals/ditaval-02.ditaval</ditavalref>
      </ditavals>
      <processParameters>
        <processParam name="param1" value="value1"/>
        <processParam name="param2" value="value2"/>
      </processParameters>
    </deliverableProcessMetadata>        
  </deliverableKeydefsetMetadata>
  <topicgroup>
    <keydef keys="key-01" href="http://example.com/publications/pub-a/topic-01.html" 
      format="html" 
      scope="external"
    />
  </topicgroup>
</deliverableAsDeliveredKeydefSet>