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" />
The <xsl:template> element is used to build templates. The match attribute is used to associate a template with an XML element. The match attribute can also be used to define a template for the entire XML document. The value of the match attribute is an XPath expression (i.e. match="/" defines the whole document).
When it matches an XML node, the template is invoked by the processor. <xsl: template match> matches the root node of the source document. If it doesn't find the match nodes, default rules are applied. The match follows an expression of Xpath.
mode. The mode attribute allows an element as specified by its Qualified Names to be processed multiple times, each time producing a different result. If <xsl:template> does not have a match attribute, it cannot have a mode attribute.
With <xsl:apply-templates> the current node moves on with every iteration, whereas <xsl:call-template> does not change the current node.
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>
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:
Write your template without a mode attribute.
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 amode
attribute, then it applies only to those template rules fromxsl:template
elements that have amode
attribute with the same value; if anxsl:apply-templates
element does not have amode
attribute, then it applies only to those template rules fromxsl:template
elements that do not have amode
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With