Can one give me the example for "mode" of template in xsl?

In

<xsl:template name="temp_name" mode="mode">

What is the meaning of mode? I searched many many resource, but i couldn't find example for that. So can anybody explain with an example?


It isn't too meaningful to give a template both a name and a mode.

The name attribute fully identifies a template and there cannot be two templates with the same name and different modes.

The mode attribute allows the same nodes to be processed more than once, using different modes.

Here is a short example:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="num[position() mod 3 = 1]">
  <tr>
    <xsl:apply-templates mode="copy" select=
     ". | following-sibling::*[not(position() >2)]"/>
  </tr>
 </xsl:template>

 <xsl:template match="*" mode="copy">
  <td><xsl:value-of select="."/></td>
 </xsl:template>

 <xsl:template match="num"/>
</xsl:stylesheet>

When this transformation is applied on the following XML document:

<nums>
  <num>01</num>
  <num>02</num>
  <num>03</num>
  <num>04</num>
  <num>05</num>
  <num>06</num>
  <num>07</num>
  <num>08</num>
  <num>09</num>
  <num>10</num>
</nums>

The result is that the numbers are displayed in three tr (rows), each containing three columns (with the possible exception of the last row):

<tr>
   <td>01</td>
   <td>02</td>
   <td>03</td>
</tr>
<tr>
   <td>04</td>
   <td>05</td>
   <td>06</td>
</tr>
<tr>
   <td>07</td>
   <td>08</td>
   <td>09</td>
</tr>
<tr>
   <td>10</td>
</tr>

In this transformation, any num element with position that cannot be represented in the form 3*k +1 (where k is an integer), is matched by a template with empty body and thus isn't processed.

However, we want to process all num elements that should form the cells of a row. For this purpuse, we are processing them using the xslt instruction:

<xsl:apply-templates mode="copy" select=
 ". | following-sibling::*[not(position() >2)]"/>

which means: "Do not apply to the selected nodes templates that would normally be applied (in no mode), but apply templates that are in copy mode"

Thus, we do not ignore the selected num elements, but are processing them in copy mode and are creating the td s of a row.

The template rule:

<xsl:template match="num"/>

is necessary to override the xslt builtin templates (default processing) that would otherwise cause the string values of the num nodes whose position cannot be represented as 3*k +1, to be output.

So, these nodes are processed by both templates:

<xsl:template match="num"/>

and

<xsl:apply-templates mode="copy" select=
 ". | following-sibling::*[not(position() >2)]"/>

and thus we get the wanted result.

It would be instructive to step through with a good XSLT debugger in order to see how these templates are applied.


<xsl:apply-templates select="phone" />
<xsl:apply-templates select="phone" mode="accountNumber"/>
<xsl:template match="phone">
      <TD>A</TD>
</xsl:template>
<xsl:template match="phone" mode="accountNumber">
      <TD>B</TD>
</xsl:template>

Link a simple example here: https://msdn.microsoft.com/en-us/library/ms256045%28v=vs.110%29.aspx


The mode attribute allows multiple ways of processing the same XML elements.

A template must have a match attribute if wanting to use a mode attribute, so they are not meant for templates relying solely upon the name attribute for calling.

They apply to xsl:apply-templates to determine which xsl:templates will respond, so an apply using a mode will only invoke a template that uses the same mode. Templates with no mode will only respond to an apply without a mode.

For example, you may want to render an XML paragraph element as a HTML p element for viewing, but as a form for editing.

This can then be rendered for viewing by:

<xsl:template match="paragraph">
 <p>...</p>
</xsl:template>

which would match paragraph tags in an XML document when called through:

<xsl:apply-templates />

Conversely, to render for editing use:

<xsl:template match="paragraph" mode="edit">
 <form>...</form>
</xsl:template>

by calling through:

<xsl:apply-templates mode="edit" />

Note that in the example, if the rest of the page is to be rendered using the non-mode xsl:apply-templates, the xsl:template mode="edit" version would have to be explicitly invoked for the specific paragraph elements to be edited.

If you don't need to have a mode match for all XML elements, provide a null template, like:

<xsl:template match="*" mode="edit" />

to make sure that you don't get 'phantom' text from deep matches polluting the output.

As with any xsl catchall template, put it at the beginning of all xsl:templates for the same mode, as xsl only uses the last matching template, and putting it last would ensure nothing is ever seen!