Replacing Direct Image References with Key References in a DITA Project.
Read time: 5 minute(s)
Suppose that you have a large DITA project and all the image references in your topics
are direct references, using the @href attribute like
this:
<image href="../../images/Iris_sanguinea.jpg" scale="50"/>
For
better scalability and reuse possibilities, suppose you want to convert these direct
references to DITA 1.2 key
references:<image keyref="Iris_sanguinea.jpg" scale="50"/>
Doing something like this manually means making replacements in hundreds of places and also manually building a DITA map that maps the image file name to the image location.
This blog post will try to describe some steps that you will help you to automate this change
in your project:
- The first big step is to generate the DITA Map that maps each image file name (which
will be used as a key) to the image location. So, the generated DITA map will look like
this:
We will assume that all images are placed in an images folder and we can create an ANT build file that lists all the images in a parameter and then calls an XSLT script to process the list of images further:<!DOCTYPE map PUBLIC "-//OASIS//DTD DITA Map//EN" "map.dtd"> <map> ….….... <keydef href="Iris_sanguinea.jpg" keys="Iris_sanguinea.jpg"/> …... </map>
<project basedir="." name="Create Image Keys Definition Map"> <fileset id="dist.contents" dir="images/" includes="*"/> <property name="prop.dist.contents" refid="dist.contents"/> <xslt in="createKeyrefsMap.xsl" style="createKeyrefsMap.xsl" out="images/imageKeydefs.ditamap" destdir="."> <param name="filesList" expression="${prop.dist.contents}"/> </xslt> </project>
The XSLT stylesheet createKeyrefsMap.xsl is responsible for creating the mapping DITA map:<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="1.0"> <xsl:param name="filesList"/> <xsl:output doctype-public="-//OASIS//DTD DITA Map//EN" doctype-system="map.dtd" indent="yes"/> <xsl:template match="/"> <map> <xsl:call-template name="tokenizeString"> <xsl:with-param name="list" select="$filesList"/> </xsl:call-template> </map> </xsl:template> <xsl:template name="tokenizeString"> <xsl:param name="list"/> <xsl:param name="delimiter" select="';'"/> <xsl:choose> <xsl:when test="contains($list, $delimiter)"> <keydef href="{substring-before($list,$delimiter)}" keys="{substring-before($list,$delimiter)}"/> <xsl:call-template name="tokenizeString"> <xsl:with-param name="list" select="substring-after($list,$delimiter)"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <keydef href="{$list}" keys="{$list}"/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
After this step you will have a new DITA map with all image mappings and afterwards you can link it in your main project's DITA map.
- We still need to make changes to all DITA topics and replace all image hrefs with
keyrefs. Oxygen has support for XML Refactoring actions and you can define custom
XSLT scripts that can be applied to modify an entire set of topics. In the
OXYGEN_INSTALL_DIR/refactoring folder, you can add an XSLT script along with an
XML description of the refactoring action. An XSLT script that would replace
@href attributes on images with @keyref would look like
this:
You can right-click anywhere in the DITA Maps Manager view and choose Refactoring->XML Refactoring, then use your custom refactoring action to modify all resources.<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:f="http://www.oxygenxml.com/ns/functions"> <xsl:function name="f:getKeyref" as="xs:string"> <xsl:param name="element" as="element()"/> <xsl:variable name="imageFile" select="tokenize(translate($element/@href, '\', '/'), '/')[last()]"/> <xsl:variable name="key" select="substring-before($imageFile, '.')"/> <xsl:value-of select="$key"/> </xsl:function> <xsl:template match="node() | @*"> <xsl:copy> <xsl:apply-templates select="node() | @*"/> </xsl:copy> </xsl:template> <xsl:template match="image[@href and not(@keyref)]"> <xsl:copy> <xsl:apply-templates select="@* except @href"/> <xsl:attribute name="keyref" select="f:getKeyref(.)"></xsl:attribute> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
A set of samples, including the build file, XSLT stylesheets, and refactoring action XML descriptor can be found here:https://www.oxygenxml.com/forum/files/batchImageHrefToKeyref.zip.