The @conrefend attribute

The @conrefend attribute is used when referencing a range of elements with the conref mechanism. The @conref or @conkeyref attribute references the first element in the range, while @conrefend references the last element in the range.

Using @conref together with @conrefend

Several items must be taken into account when using or implementing @conrefend.

  • Processors will resolve the range by pulling in the start target and following sibling XML nodes across to and including the end target.
  • The start and end elements of a range MUST be of the same type as the referencing element or generalizable to the referencing element. For example, @conref and @conrefend attributes on an <li> element might reference other <li> elements, or they might reference specializations of <li> such as <step>.
  • As with @conref, if the @conrefend references a more specialized version of the referencing element, applications should generalize the target when resolving.
  • It is not valid to use @conrefend to reference a more general version of an element (such as using <step> to reference an <li> element).
  • Other nodes (such as elements or text) between the start and end of a range do not have to match the referencing element.
  • The start and end elements in a range MUST share the same parent, and the start element MUST precede the end element in document order.
  • The parent of the referencing element MUST be the same as the parent of the referenced range or generalizable to the parent of the referencing element. For example, it is possible to pull a range from <conbody> into <body>, because <conbody> is generalizable to <body>. It is not possible to pull a range from <body> into <conbody>, because the result might not be valid in <conbody>.
  • With single conref, an @id attribute from the referenced element will not be preserved on the resolved content. With a range, an @id on both the start and the end elements will not be preserved. @id attributes on intermediate or child nodes should be preserved; if this results in duplicate @id values, an application can recover by changing the @id, warning the user, or implementing another strategy.
  • With a single conref, attributes specified on the referencing elementcan be used to override attributes on the referenced element. With a conref range, the same is true, with the following clarifications:
    • When an @id attribute is specified on the referencing element, it will only be preserved on the first element of the resolved range.
    • When other attributes are specified, they will only apply to referenced elements of the same type. For example, if <step> is used to pull in a range of sequential <step> elements, locally specified attributes apply to all steps in the range. If <ol> is used to pull in a series of (<ol>, <p>, <ol>), locally specified attributes apply only to the <ol> elements in that range.

Example: reusing a set of list items

Figure 1. List example: Source topic.dita with ids
<topic id="x">
 	...
 	<body>
 		<ol>
 			<li id="apple">A</li>
 			<li id="bear">B</li>
 			<li id="cat">C</li>
 			<li id="dog">D</li>
 			<li id="eel">E</li>
 		</ol>
 	</body>
 </topic>
 
Figure 2. List example: Reusing topic with conrefs
 <topic id="y">
 	...
 	<body>
 		<ol>
 			<li>My own first item</li>
 			<li conref="topic.dita#x/bear" conrefend="topic.dita#x/dog"/>
 			<li>And a different final item</li>
 		</ol>
 	</body>
 </topic>
 
Figure 3. List example: Processed result of reusing topic
 <topic id="y">
 	...
 	<body>
 		<ol>
 			<li>My own first item</li>
 			<li>B</li>
 			<li id="cat">C</li>
 			<li>D</li>
 			<li>And a different final item</li>
 		</ol>
 	</body>
</topic>

Example: Reusing a set of blocks

Figure 4. Block level example: Source topic.dita with ids
<topic id="x">
 	...
 	<body>
   <p id="p1">First para</p>
 	 <ol id="mylist">
     <li id="apple">A</li>
     <li id="bear">B</li>
     <li id="cat">C</li>
     <li id="dog">D</li>
     <li id="eel">E</li>
   </ol>
   <p id="p2">Second para</p>
 	</body>
 </topic>
 
Figure 5. Block level example: Reusing topic with conrefs
 <topic id="y">
 	...
 	<body>
 		<p conref="topic.dita#x/p1" conrefend="topic.dita#x/p2"/>
 	</body>
 </topic>
Figure 6. Block level example: Processed result of reusing topic
 <topic id="y">
 	...
 	<body>
    <p>First para</p>
 	  <ol id="mylist">
      <li id="apple">A</li>
      <li id="bear">B</li>
      <li id="cat">C</li>
      <li id="dog">D</li>
      <li id="eel">E</li>
    </ol>
    <p>Second para</p>
 	</body>
</topic>

Using @conrefend together with @conkeyref

When the @conkeyref attribute is used in place of @conref, a key is used to address the target of the reference. The @conrefend attribute, which indicates the end of a @conref range, cannot use a key. Instead the the map or topic element addressed by the key name component of the @conkeyref is used in place of whatever map or topic element is addressed by the @conrefend attribute.

For example, if the value of the @conkeyref attribute is "config/step1" and the value of the @conrefend is defaultconfig.dita#config/laststep, the conref range will end with the step that has id="laststep" in whatever topic is addressed by the key name "config". If the key name "config" is not defined, and the @conref attribute itself is not present for fallback, the @conrefend attribute is ignored.

Example: Combining @conrefend with @conkeyref

Figure 7. Defining and referencing a key with @conkeyref

In this example the key "xmp" is defined as the first topic in the file examples.dita.

<map>
  <!-- ... -->
  <keydef keys="xmp" href="examples.dita"/>
  <!-- ... -->
</map>

examples.dita:
<topic id="examples">
  <title>These are examples</title>
  <body>
    <ul>
      <li id="first">A first example</li>
      <li>Another trivial example</li>
      <li id="last">Final example</li>
    </ul>
  </body>
</topic>
To reuse these list items by using the key, the @conkeyref attribute combines the key itself with the sub-topic id (first) to define the start of the range. The @conrefend attribute defines a default high-level object along with the sub-topic id (last) that ends the range:
  <li conkeyref="xmp/first" 
      conrefend="default.dita#default/last"/>

The @conkeyref attribute uses a key to reference the first topic in examples.dita, so the range begins with the object examples.dita#examples/first. The high-level object in the @conrefend attribute (default.dita#default) is replaced with the object represented by the key (the first topic in examples.dita), resulting in a range that ends with the object examples.dita#examples/last.

Figure 8. Combining @conref, @conkeyref, and @conrefend

When @conref, @conkeyref, and @conrefend are all specified, the key value takes priority.

  <li conkeyref="thisconfig/start"
      conref="standardconfig.dita#config/start"
      conrefend="standardconfig.dita#config/end"/>
  • If the key "thisconfig" is defined as mySpecialConfig.dita#myconfig, then the range will go from the list item with id="start" to the list item with id="end" in the topic mySpecialConfig.dita#myconfig.
  • If the key "thisconfig" is defined as myConfig.dita, then the range will go from the list item with id="start" to the list item with id="end" within the first topic in myConfig.dita.
  • If the key "thisconfig" is not defined, then the unchanged @conref and @conrefend attributes are used as fallback. In that case, the range will go from the list item with id="start" to the list item with id="end" within the topic standardconfig.dita#config.

Error conditions

When encountering an error condition, an implementation can issue an error message.

Condition or Issue Result
The @conref attribute cannot be resolved in the target document (the target element might have been removed or its id has changed). The @conref is ignored.
The @conrefend attribute cannot be resolved in the target document (the target element might have been removed or its id has changed). Range cannot be resolved, optional recovery processes the result as a simple conref.
Start and end elements are not siblings in the target document. If the start element exists, optional recovery processes the result as a simple conref.
End element occurs before the start element in the target document. If the start element exists, optional recovery processes the result as a simple conref.
An element has a @conrefend attribute but is missing the @conref attribute. No result.