I have the following XSLT templates
<xsl:template match="body/table/rows">
<fo:table-row font-weight="bold">
<fo:table-cell>
<fo:block>
<xsl:value-of select="date" />
</fo:block>
</fo:table-cell>
..............
</fo:table-row>
</xsl:template>
<xsl:template match="body/table/result">
<fo:table-row>
<fo:table-cell>
<fo:block>
<xsl:value-of select="date" />
</fo:block>
</fo:table-cell>
..............
</fo:table-row>
</xsl:template>
the difference in the templates is that for the element <fo:table-row> there is font-weight="bold" and the other one doesn't have, however the content of both templates which is made of <fo:table-cell is the same,clearly this is a code duplication. Is there a way to remove this code duplication?
CodePudding user response:
Try this:
<xsl:template match="body/table/rows | body/table/result">
<fo:table-row>
<xsl:apply-templates select="." mode="font-weight"/>
<fo:table-cell>
<fo:block>
<xsl:value-of select="date" />
</fo:block>
</fo:table-cell>
..............
</fo:table-row>
</xsl:template>
<xsl:template match="body/table/rows" mode="font-weight">
<xsl:attribute name="font-weight">bold</xsl:attribute>
</xsl:template>
<xsl:template match="*" mode="font-weight"/>
CodePudding user response:
Use a mode:
<xsl:template match="*" mode="cell">
<fo:table-cell>
<fo:block>
<xsl:value-of select="date" />
</fo:block>
</fo:table-cell>
</xsl:template>
and apply-templates where you had the fo:table-cell elements, i.e. use <xsl:apply-templates select="." mode="cell"/>.
You could also think about parameterizing the template and including the fo:table-row with the font weight as a parameter.
CodePudding user response:
IMHO, the simplest solution in your case would be to add the attribute conditionally:
<xsl:template match="rows | result">
<fo:table-row>
<xsl:if test="self::rows">
<xsl:attribute name="font-weight">bold</xsl:attribute>
</xsl:if>
<fo:table-cell>
<fo:block>
<xsl:value-of select="date" />
</fo:block>
</fo:table-cell>
<!-- .... -->
</fo:table-row>
</xsl:template>
A more generic solution would place the common code in a named template and call that template from both specific templates, or - in XSLT 2.0 and higher - use the xsl:next-match instruction.
Untested because no input example was provided.
