xsltdita

How do I get a new DITA tag to carry over to my output using XSLT?


I had successfully updated my XSLT to script to add the audience tag to my output but I was asked for the output to display slightly differently.

My original input looked like this:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE bookmap PUBLIC "-//OASIS//DTD DITA BookMap//EN" "bookmap.dtd" []>
<bookmap>
<topicgroup>
            <topichead navtitle="Arkansas Property and Casualty Adjuster Law" locktitle="yes" audience="Arkansas">
                <topicgroup>
                    <mapref href="Qbank/maps/Adj_Unit_AR.ditamap" format="ditamap"/>
                </topicgroup>
            </topichead>
        </topicgroup>
</bookmap>

The portion of my original script looked like this:

<xsl:template match="*[contains(@class,' mapgroup-d/topichead ')]">
        <topichead>
            <xsl:attribute name="navtitle">
                <xsl:value-of select="@navtitle"/>
            </xsl:attribute>
             
            <xsl:choose>
                <xsl:when test="@audience">
                    <xsl:attribute name="audience">
                        <xsl:value-of select="@audience"/>  
                    </xsl:attribute>
                </xsl:when>
                <xsl:otherwise /> 
            </xsl:choose>
      </topichead>
</template>

But now I'm being asked to move the audience tag to a different spot and I'm having trouble getting the transform to grab the tag.

My new input looks like this:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE bookmap PUBLIC "-//OASIS//DTD DITA BookMap//EN" "bookmap.dtd" []>
<bookmap>
<chapter navtitle="Alabama Property and Casualty Adjuster Law" locktitle="yes" audience="Alabama">
        <topicgroup            
                <topicgroup>
                    <mapref href="Qbank/maps/Adj_Unit_AL.ditamap" format="ditamap"/>
                </topicgroup>            
        </topicgroup>
    </chapter>
</bookmap>

This is the script I tried but it's not pulling over the audience tag.

<xsl:template match="*[contains(@class,' mapgroup-d/topichead ')]">
        <topichead>
            <xsl:attribute name="navtitle">
                <xsl:value-of select="@navtitle"/>
            </xsl:attribute>
             
            <xsl:choose>
                <xsl:when test="bookmap/chapter/@audience">
                    <xsl:attribute name="audience">
                        <xsl:value-of select="@audience"/>  
                    </xsl:attribute>
                </xsl:when>
                <xsl:otherwise /> 
            </xsl:choose>
      </topichead>
</template>

What am I doing wrong?


Solution

  • This xsl:when expression:

     <xsl:when test="bookmap/chapter/@audience">
    

    is a relative xpath, meaning that the XSLT processor searches for an element "bookmap" which is a child of the current "topichead" element matched by the xsl:message. You need to search upwards, something like:

     <xsl:when test="ancestor::chapter/@audience">
    

    Then this value-of:

     <xsl:value-of select="@audience"/>
    

    it's a relative xpath expression again, relative to the current "topichead" element matched by the xsl:template. So you would probably need to replace it with:

    <xsl:value-of select="ancestor::chapter/@audience">