Edit online

Sorting Glossary Lists in a DITA Bookmap

Read time: 4 minute(s)

The idea behind this DITA refactoring action started from this forum post: https://www.oxygenxml.com/forum/viewtopic.php?f=2&t=15284&p=45137#p45137.

Suppose you have a DITA Bookmap that at some point references all of its glossary entries:
                <topicref href="glossary/glossItem1.dita"/>
                <topicref href="glossary/glossItem2.dita"/>
                <topicref href="glossary/glossItem3.dita"/>
                <topicref href="glossary/glossItem4.dita"/>
and you want to have all of these glossary topics sorted alphabetically by title as they appear in the PDF output.

One option for this is to create a PDF customization that automatically sorts the glossary entries no matter what order they were originally specified in the DITA Map.

The other option is to create a custom Oxygen XML Refactoring operation that, when applied on the DITA Bookmap containing the "glossarylist", will sort the glossentries in alphabetical order according to the title of each glossentry.

The following steps will help you achieve this:
  1. Somewhere on disk, create a folder (for example, customRefactor) and add a reference to it in the Oxygen Preferences->"XML / XML Refactoring" page.

  2. In that custom folder, create an XML file (for example, sortGlossentries.xml) that has the following content:

        xmlns="http://www.oxygenxml.com/ns/xmlRefactoring" id="op_tck_rp1_hcb" name="Sort glossentries">
        <description>Sort glossentries.</description>    
        <script type="XSLT" href="sortGlossentries.xsl"/>

    This particular descriptor file contains the name of the operation, its description, and points to an XSLT stylesheet that will be applied to sort the entries in the DITA Bookmap.

  3. In the same folder, create a file called sortGlossentries.xsl with the following content:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        <xsl:template match="node() | @*">
                <xsl:apply-templates select="node() | @*"/>
        <xsl:template match="glossarylist | topicgroup[@outputclass='glossarylist']">
                <xsl:apply-templates select="@*"/>
                <xsl:variable name="closestXMLLang" select="ancestor-or-self::*[attribute::xml:lang][1]/@xml:lang"/>
                    <xsl:when test="exists($closestXMLLang)">
                        <xsl:for-each select="*" >
                            <xsl:sort select="document(@href, .)/*/glossterm/text()" lang="{$closestXMLLang}" case-order="lower-first"/>
                            <xsl:apply-templates select="."/>
                        <xsl:for-each select="*" >
                            <xsl:sort select="document(@href, .)/*/glossterm/text()" case-order="lower-first"/>
                            <xsl:apply-templates select="."/>

    This particular XSLT processing copies almost all the Bookmap content unchanged. However, the topicrefs in the glossarylist are sorted according to the glossterm titles specified inside each of them.

  4. Restart Oxygen.

  5. Open the bookmap that contains the glossarylist in the Oxygen main editing area, right-click, choose Refactoring and in the Other operations submenu you will find the new Sort glossentries refactoring action. Invoke the action and use the Preview button to check if the sorting is properly done.

The XML Refactoring XML descriptor and XSLT stylesheet can also be found here: https://github.com/oxygenxml/dita-refactoring-examples/tree/master/18.%20Sort%20Glossentries.