Home > Blockchain >  How to remove code duplication in template
How to remove code duplication in template

Time:01-27

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.

  •  Tags:  
  • Related