templatesxsltapply-templates

XSLT 1.0: put conditions into match attribute or apply-templates?


I have a general question regarding <xsl:template match=""> and <xsl:apply-templates/>.

I have the case where I match the element E1EDP01. But no all E1EDP01 elements should be matched, only a certain range.

But now what is the correct way of matching only a certain range of elements?

Is it correct to do it this way:

<xsl:apply-templates select="E1EDP01"/>

and the template that restricts the range of E1EDP01:

<xsl:template match="E1EDP01[not(PSTYV='ZDAE')][E1EDP02[QUALF='001']/ZEILE]">
...
</xsl:template>

Or do I have to change the apply-templates to:

<xsl:apply-templates select="E1EDP01[not(PSTYV='ZDAE')][E1EDP02[QUALF='001']/ZEILE]"/>

Solution

  • Both work, but they express slightly different intentions. The specific matching template says "this is how you should always process this kind of E1EDP01 element", and the <xsl:apply-templates select="E1EDP01"/> says "process all my E1EDP01 elements now". Whereas having a generic template and a specific apply says "I want to process these particular E1EDP01 elements now (but I might want to process others later)" and "this is how you process any E1EDP01".

    Which approach is better really depends on whether the [not(PSTYV='ZDAE')][E1EDP02[QUALF='001']/ZEILE] is something inherent to the way the elements should be handled, or something specific to what you want to do at one particular place in the stylesheet. For example, if I had some XML describing financial transactions and I had a rule that negative amounts always had to be displayed in a red box, then I might define

    <xsl:template match="amount[. &lt; 0]">
      <redbox><xsl:value-of select="."/></redbox>
    </xsl:template>
    <xsl:template match="amount"><xsl:value-of select="."/></xsl:template>
    

    If instead I wanted to include a summary redbox with all the negative amounts, but display the amounts normally elsewhere then I would probably choose to use a single template for amount but then filter at the apply-templates point

    <redbox>
      <xsl:apply-templates select="amount[. &lt; 0]" />
    </redbox>
    

    You have to choose the approach that makes most sense for your task.