Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can an XSL template match in *ALL* modes?

Tags:

xslt

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" />
like image 664
Dirk Vollmar Avatar asked Jan 26 '09 12:01

Dirk Vollmar


People also ask

What does xsl template element do?

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).

What happens if a template XPath does not match anything?

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.

What is mode in xsl template?

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.

What is the difference between call template and apply template in XSLT?

With <xsl:apply-templates> the current node moves on with every iteration, whereas <xsl:call-template> does not change the current node.


2 Answers

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>
like image 111
annakata Avatar answered Sep 23 '22 19:09

annakata


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.

like image 28
Dimitre Novatchev Avatar answered Sep 20 '22 19:09

Dimitre Novatchev