Modifying XSL transforms
The next level of change you can make involves changes to the actual DITA OT XSL transforms. The changes you can make range from minor output changes to massive changes in the XSL -processing.
The changes you make in CSS usually take little time, but have a big visual effect. Most of the changes you need to make to get the output looking the way you want will be in CSS. By contrast, the changes you make in XSL are often very necessary, will have much lower visual impact, but will consume a large amount of your time and effort.
The payoff is that modifications to XSL can accomplish things that cannot be done any other way. The changes you can make vary widely in scope and complexity:
- The DITA OT provides a number of empty XSL templates that are intended to handle headers, footers, and the like (these are called “stub” templates). Unlike the boilerplate headers and footers mentioned earlier in this paper, these templates allow you to incorporate information from the DITA source you’re processing. For example, a template can find the most recent <title> element used in a <topic> or <section> and include it in a running header.
- Output different HTML tags to produce different results. For instance, replacing a <p> tag in HTML with a <div> tag (perhaps including a class attribute).
- Use information in the DITA content in a different order or different way from which it was -originally intended. For instance, adding a summary of the subheads at the beginning of a topic, or filtering out elements based on an attribute value (conditional text).
- Add capabilities that are not in the current stylesheets. For example, adding the ability to sort items in a list (see Modifying transforms: sorting <ul> lists).
- At the high end of modifications you can make, you can create a specialization to support content not handled in standard DITA topics. Specializations themselves can range from adding new elements into existing topics to implementation of a new topic type.
Apart from using the stub XSL templates and true specialization, most of these approaches represent varying degrees of hacks.
Stub templates provided by the DITA OT
The DITA OT predefines a number of named templates that provide common functions, such as headers, footers, and side-TOCs.
These templates are in ditaot\xsl\xslhtml\dita2htmlImpl.xsl; each template is named gen-user-*. The templates are listed in Table 2. The idea is that you should copy the template to your own XSL stylesheet file and make your modifications there. However, in the spirit of hacking, until you get around to creating your own XSL file, you can make the modification directly in dita2htmlImpl.xsl.
Table 2: DITA OT Stub Templates
|
Stub template |
Purpose |
|
gen-user-head |
Create additional information for the HTML <head> tag. You can use this template to add dynamic metadata to the output HTML. |
|
gen-user-header |
Generate header information. |
|
gen-user-footer |
Generate footer information. |
|
gen-user-sidetoc |
Generate a list of subordinate topics or sections. |
|
gen-user-scripts |
Generate JavaScripts for the document. |
|
gen-user-styles |
Generate style (CSS) information for the document. |
|
gen-user-external-link |
Handle links to external information. Note that this is the only template for which there is no <xsl:call-template> directive in the dita2htmlImpl.xsl stylesheet. To implement this, you’ll need to modify the template that handles topic/xref (for HTML, usually ditaot/xsl/xslhtml/rel-links.xsl). |
|
gen-user-panel-title-pfx |
Generate a prefix for the topic title. You might use this if you need to number topics. |
There is some overlap with the HTML header and footer files described earlier in this paper. The difference is that the HTML files are static; each file is included in the output stream with no further processing. The XSL stub templates allow you to generate content dynamically, based on other information, such as the content of the DITA source topic, Ant parameters (for example, a draft stamp), or system and environment information (for example, the date).
The following example illustrates modifications to the gen-user-header template (shown in bold). The XSL does two things: it emits the message “Using override header.” to the DITA OT log file and adds a paragraph indicating the name of the root element of the topic.
<!-- Override the template in dita2htmlImpl.xsl -->
<xsl:template match="/|node()|@*" mode="gen-user-header">
<xsl:message>Using override header.</xsl:message>
<p class="mytitle">
This is a <xsl:value-of select="name()"/>.
</p>
</xsl:template>
In the command window, you should see lines such as these (the DITA OT renders the -<xsl:message> directive as a Warning):
[xslt] Processing C:\DITA-OT1.4.2.1\ant\temp\tasks\washingthecar.xml
to C:\DITA-OT1.4.2.1\ant\out\samples\xhtml\tasks\washingthecar.html
[xslt] file:/C:/DITA-OT1.4.2.1/xsl/xslhtml/dita2htmlImpl.xsl:4467:14:
Warning! Using override header.
Each output file will contain something like:

The line “This is a concept.” comes from the new header.
Creating an override template describes how to formalize this change.
Combining this concept with the CSS concepts described earlier in this paper, you could add mytitle to a CSS file so that the header stands out more clearly.
Element matching in the DITA OT
Before looking further at XSL stylesheets in the DITA OT, it’s important to understand how the DITA OT matches XML elements.
If you are familiar with XSL stylesheets, you know that a <xsl:template> declaration includes an XPath expression in its match attribute. Similarly, an <xsl:apply-templates> directive often uses a select attribute that also contains an XPath expression. The XPath expressions used in the match and select attributes usually match the name of a specific element.
Therefore, a template that handles the element named javaClass might begin with:
<xsl:template match="javaClass">
However, the DITA OT requires a slightly different strategy. Because each layer of specialization inherits behaviors from the more general layers above it, each element usually contains information listing each of those previous layers. To implement this behavior, a preprocessing stage in the DITA OT creates a class attribute for every element in a DITA source file. The new class attribute contains a space-separated list of topic-name/element-name pairs. For example, the JavaAPIRef specialization is a further specialization of the APIRef and Reference specializations, which both are specializations of Topic. As a result, the class attribute for a javaClass element is:
class="- topic/topic reference/reference apiRef/apiRef apiClassifier/apiClassifier
javaClass/javaClass "
To match elements, the DITA OT uses the contains() function to determine if an element’s class attribute contains the appropriate topic-name/element-name pair. Therefore, a template that matches a javaClass element begins:
<xsl:template match="*[contains(@class,' javaClass/javaClass
')]">
...
That is, match all elements where the class attribute contains “ javaClass/javaClass ”. The class attribute is useful because this same element can also be matched by:
<xsl:template match="*[contains(@class,' topic/topic ')]">
And anything in between.
| NOTE: | The spaces between the single quote and the beginning or end of the topic-name/element-name pair are important (for example, ' javaClass/javaClass ' and ' topic/topic '), because they prevent mis-matches of the topic-name and element-name. Without the spaces, the function “contains(@class,'javaClass/javaClass')” could also match javaClass/javaClassDetail in another class attribute, which is incorrect. |
Modifying transforms: sorting <ul> lists
The following example enables the DITA OT to sort the contents of an unordered list. (Perhaps the content includes a list of terms that must be presented alphabetically.) The file ditaot/samples/concepts/tools.xml contains an ideal list for this example: an unordered list that itemizes a set of tools. By applying this change, you can sort the list.
This modification takes advantage of another hook for hacking the DITA OT: the otherprops attribute is defined for all DITA elements. It’s useful because its definition is left entirely open. The only caution about using it is to make sure that no one else modifying the same toolkit is using the otherprops attribute for their own purposes.
To start, edit tools.xml and add an otherprops attribute to the <ul> element (shown in bold):
...
Useful tools include the following items:</p>
<ul otherprops="sort">
<li>Hammer</li>
<li>Screw driver set</li>
...
The next problem is determining where <ul> is handled. The DITA Language Reference (The DITA Language Reference is included in the DITA OT files in ditaot/doc/ditaref-book.chm or ditaref-book.pdf. The DITA sources are in ditaot/doc/langref. ) indicates that ul is defined by the generic topic, so the template will match on “ topic/ul ”. A quick search of the ditaot/xsl folder shows that the template to modify is in ditaot/xsl/xslhtml/dita2htmlImpl.xsl. (Working with the DITA OT would be almost impossible without a good search tool. I use AgentRansack, a free version of FileLocator Pro, to search for strings in Windows files and directories. For more information, see http://www.mythicsoft.com/agentransack/).
Before doing anything else, make a backup copy of this file.
After finding the template to modify, add an <xsl:choose> directive (shown in bold) to detect the value “sort” in the otherprops attribute and implement the new behavior:
<xsl:template match="*[contains(@class,' topic/ul ')]"
mode="ul-fmt">
...
<xsl:apply-templates select="@compact"/>
<xsl:call-template name="setid"/>
<xsl:choose>
<xsl:when test="contains(@otherprops,'sort')">
<xsl:message>SORTING!!!!!</xsl:message>
<xsl:apply-templates>
<xsl:sort />
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</ul>
...
Run the DITA OT:
ant -f ant/my_xhtml.xml
When the DITA OT processes tools.xml, it displays the message indicating that the sort is -occurring:
...
[xslt] Processing C:\DITA-OT1.4.2.1\ant\temp\concepts\tools.xml
to C:\DITA-OT1.4.2.1\ant\out\samples\xhtml\concepts\tools.html
[xslt] file:/C:/DITA-OT1.4.2.1/xsl/xslhtml/dita2htmlImpl.xsl:1155:23:
Warning! SORTING!!!!!
...
Open the file ditaot/ant/out/samples/xhtml/concepts/tools.html in a browser to see the sorted list.

Next Page:
Packaging up your overrides
