Re: Matching templates, named templates or for-each? My rules of

In XSLT 1.0, I think I’d do what you’ve done, except that I’d probably use a parameter in the base template, as in

<xsl:template match="docbook:section" name="sectionHandler">
  <xsl:param name="section" select="." />
  <!-- generic processing for section -->
</xsl:template>

and refer to $section rather than the context node in the body of the template. Or, knowing me, and although I can’t justify it, I’d use a mode, and do

<xsl:template match="*" mode="sectionHandling">
  <!-- generic processing for section -->
</xsl:template>

<xsl:template match="docbook:section">
  <xsl:apply-templates select="." mode="sectionHandling" />
</xsl:template>

Then, create a template for the specialisation that applies templates to that element in the same mode:

<xsl:template match="mystuff:supersection">
  <xsl:apply-templates select="." mode="sectionHandling" />
</xsl:template>

In XSLT 2.0, I’d create a function to test whether something was a section:

<xsl:function name="docbook:is-section" as="xs:boolean">
  <xsl:param name="node" as="element()" />
  <xsl:apply-templates select="$node" mode="docbook:is-section" />
</xsl:function>

<xsl:template match="docbook:section" mode="docbook:is-section" as="xs:boolean">
  <xsl:sequence select="true()" />
</xsl:template>

<xsl:template match="*" mode="docbook:is-section" as="xs:boolean">
  <xsl:sequence select="false()" />
</xsl:template>

and use that function in the match pattern for my generic template:

<xsl:template match="*[docbook:is-section(.)]">
  <!-- generic processing for section -->
</xsl:template>

Then, in the stylesheet for my specialisation, add

<xsl:template match="mystuff:supersection" mode="docbook:is-section" as="xs:boolean">
  <xsl:sequence select="true()" />
</xsl:template>

(ie register <mystuff:supersection> as being a Docbook section).

If I needed to do extra things to the <mystuff:supersection> element, I can use <xsl:next-match> (or <xsl:apply-imports>) to get the basic result:

<xsl:template match="mystuff:supersection">
  <!-- other stuff -->
  <xsl:next-match />
  <!-- other stuff -->
</xsl:template>

In XSLT 2.0 Schema-Aware, you could use substitution groups to do the same kind of thing, even without using a full schema. But you would be limited to a single inheritance hierarchy, which might or might not fit your specialisations. User-defined functions like the above, on the other hand, can classify elements into groups in any way that you like.

The downside of this design is that it depends on you knowing, when you create the base stylesheet, what kind of specialisations you’re going to have. Plus it’s a lot more verbose than the method you describe.

Reply

The content of this field is kept private and will not be shown publicly.