tags:

views:

384

answers:

2

I have two templates matching the same attributes, both with different modes (shown below). Is there a way that I can avoid writing the attributes twice, one for each template, and instead store those attributes in say a variable? So instead of the match statements below I would have a match like match=$styleAttributes, and styleAttributes would be set to all the attributes. This would be using version 2.0 (Saxon 9.1.0.7). Thanks.

<xsl:template match="@width|@height|@visible|@vAlign|@hAlign|@zOrder|@hOffset|@vOffset|@color|@fontSize" mode="styles">
    <!-- Do something -->
</xsl:template> 

<!-- Do nothing -->  
<xsl:template match="@width|@height|@visible|@vAlign|@hAlign|@zOrder|@hOffset|@vOffset|@color|@fontSize" mode="common" />
+1  A: 

Well, you can match on everything with "@*" and then within the template check the local-name() against a global variable, and then call another template with a different @mode= depending on pass-fail.

SO is an awesome resource, but for pure XSLT questions, nothing beats the xsl-list run by Mulberry Technologies. It is well-represented by vendors and users of XSLT products, as well as by the members of the W3C committees responsible for the specs.

lavinio
Ok, thanks. I will check the list out.
Steve
The only problem here is that doing so might affect optimizations done by XSLT processor.
Pavel Minaev
A: 

Even in XSLT 2.0 a match pattern can only contain a veriable reference as part of a predicate or as part of the argument (expression) for the key() or id() functions. This determines the negative answer to the direct question.

However, if we need to avoid repeating the same match pattern in two templates that only differ by mode, then one way to achieve this is to use only a single template with no mode and to pass (what used to be) the mode as a parameter to the template.

Here is a small example:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 >
 <xsl:output method="text"/>

    <xsl:template match="/*">
     <xsl:apply-templates select="@*"/>
    </xsl:template>

    <xsl:template match=
    "@width|@height|@visible|@vAlign|@hAlign|@zOrder|@hOffset|@vOffset|@color|@fontSize">
      <xsl:param name="procMode" as="xs:string" select="'common'"/>

     <xsl:sequence select=
      "if($procMode = 'common')
        then
          'Hello from the Common Processor'
        else
          'Hello from the Styles Processor'
      "
      />
    </xsl:template>
</xsl:stylesheet>

When the above transformation is applied on this XML document:

<div width="50"/>

the wanted result is produced:

Hello from the Common Processor

Dimitre Novatchev