Dirk Vollmar
Dirk Vollmar

Reputation: 176219

Can an XSL template match in *ALL* modes?

Is there a way to write an XSL 1.0 template which is matching in all modes?

Or do I have to write a separate template for every existing mode (including additional templates for modes being added in the future)?

Here is what I have:

<xsl:apply-templates mode="mode1" />
    ...
<xsl:apply-templates mode="mode2" />
    ...
<!-- Do not process text content of nodes no matter in what mode -->
<!-- Is there a way to have only one template here? -->
<xsl:template match="text()" mode="mode1" />
<xsl:template match="text()" mode="mode2" />

Upvotes: 14

Views: 12106

Answers (3)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243529

Is there a way to write an XSL 1.0 template which is matching in all modes

Yes, in order to do this one should follow these two rules:

  1. Write your template without a mode attribute.

  2. Within the moded templates have an <xsl:apply-templates> instruction without a mode attribute that will result in the template in 1. above being selected for processing

This follows directly from the XSLT 1.0 spec, which says:

If an xsl:apply-templates element has a mode attribute, then it applies only to those template rules from xsl:template elements that have a mode attribute with the same value; if an xsl:apply-templates element does not have a mode attribute, then it applies only to those template rules from xsl:template elements that do not have a mode attribute.

To summarise: A set of templates each in a different mode can still issue <xsl:apply-templates> in such a way (described above), so that the same specific, single template will be selected for processing in each case.

Upvotes: 2

annakata
annakata

Reputation: 75862

The predefined mode: #all (only available in XSLT 2.0 however).

edit: replicating shared mode behaviour with 1.0

<xsl:template match="/">
    <xsl:variable name="choice" select="'a'"/><!-- input seed here -->
    <xsl:choose>
        <xsl:when test="$choice='a'">
            <xsl:apply-templates mode="a"/>
        </xsl:when>
        <xsl:when test="$choice='b'">
            <xsl:apply-templates mode="b"/>
        </xsl:when>
    </xsl:choose>
</xsl:template>

<xsl:template match="*" mode="a">
    [A]
    <xsl:apply-templates />
</xsl:template>

<xsl:template match="*" mode="b">
    [B]
    <xsl:apply-templates />
</xsl:template>

<xsl:template match="text()">
    [ALL]
</xsl:template>

Upvotes: 7

Alex
Alex

Reputation: 13239

If you want to have the template match in all modes then why are you using mode? If you don't use mode then the template will be used all the time. The reason for mode is to conditionally do different things with the same data type. Seems like you want modeless.

Upvotes: 1

Related Questions