Avoiding Conflicting Rules by Using <xsl:apply-imports>

MSXML 5.0 SDK

Microsoft XML Core Services (MSXML) 5.0 for Microsoft Office - XSLT Developer's Guide

Avoiding Conflicting Rules by Using <xsl:apply-imports>

The previous topic, Deciding Whether to Import or Include an XSLT File, discussed some advantages of using imported (vs. included) style sheets. This topic discusses another important advantage of imported style sheets.

The declarations of an included style sheet are either applied or not applied, depending on whether there are conflicting declarations in the including style sheet, and on the sequence in which the conflicting declarations appear.

When you import a style sheet, however, you have another option. You can supplement the imported declarations with others. To do so, the importing style sheet needs an appropriate <xsl:import> element, as always. However, an <xsl:apply-imports> element also appears at the appropriate point in the template rule. This template rule would otherwise simply override its counterpart in the imported style sheet.

The syntax of the empty <xsl:apply-imports> element is straightforward. It does not even include any attributes:

<xsl:apply-imports/>

To see how this can be used, consider the files discussed earlier in this topic:

The above version of jamming.xsl contains template rules for processing fiction-related elements in the Synchronized Jamming book. It also includes two style sheets, via <xsl:include>. These included style sheets handle other elements, such as markup code and musical annotations.

To illustrate the advantage of supplemental imported declarations, we'll begin by changing the following line in jamming.xsl.

<xsl:include href="chord.xsl"/>

The new line is as follows:

<xsl:import href="chord.xsl"/>
Note   Because any <xsl:import> elements must be the first top-level elements in a style sheet, we also have to move this line to a position above the <xsl:include href="markup_code.xsl"/> element in jamming.xsl.

So far, this has no effect on the output as viewed in Internet Explorer. No conflict is introduced, because jamming.xsl itself has no template rules for processing jamming.xml's <chord> element, its attributes, or its child elements.

However, the production designers of Synchronized Jamming do face a conflict. The conflict is not between template rules, but between design standards. According to these design standards, any table embedded in a Web page must be surrounded by a double box, to make it stand out from plain text. The production designers have three choices for resolving the design conflict:

  1. Do nothing. They can accept ScootMusic's styling of the <chord> element as a borderless table, and therefore discard, for this book only, their own design standards for tables.
  2. Physically copy and paste the contents of chord.xsl's template rule into jamming.xsl. The drawback here is that if ScootMusic ever changes chord.xsl, Synchronized Jamming's designers will have to re-edit jamming.xsl to maintain consistency.
  3. Use an <xsl:apply-imports> element to customize the table's appearance. This way, they can incorporate chord.xsl's template rule for the <chord> branch of the source tree, and double-border it as well.

For option #3, add a template rule for the <chord> element to jamming.xsl, as follows:

<xsl:template match="chord">
   <div style="border-style:double; width:50%">
      <xsl:apply-imports/>
   </div>
</xsl:template>

The XSLT processor creates the bordered <div> element in the result tree at the point of the source tree's <chord> element. Then, at the point of the <xsl:apply-imports>, the processor examines all imported style sheets to see if they also provide a template rule for the <chord> element. If so, the imported template rule is fired within the resulting <div> element. The effect is as though the only template rule for the <chord> element was the following (the portion from chord.xsl is in bold):

<xsl:template match="chord">
   <div style="border-style:double; width:50%">
      <div style="width:75%; margin-left:20; padding:10">
         <table border="0">
            [and so on]
         </table>
      </div>
   </div>
</xsl:template>

Formatted Output

When viewed in Internet Explorer, the relevant portion of the page now appears as follows: