2

I am trying to transform an XML document through a series of XSL stylesheets transformations in oXygen. I found the question Is daisy chaining xslt an accepted practice? and Dimitre Novatchev's answer (below) is great: it works perfectly as set out for two pass. I can't seem to get this to work for a third pass however.

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:variable name="vPass1" >
   <xsl:apply-templates select="/*/*"/>
  </xsl:variable>
   <xsl:apply-templates mode="pass2"
        select="$vPass1/*"/>
 </xsl:template>

 <xsl:template match="num[. mod 2 = 1]">
  <xsl:copy-of select="."/>
 </xsl:template>

 <xsl:template match="num" mode="pass2">
  <xsl:copy>
    <xsl:value-of select=". *2"/>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

I've tried adding a second variable as below (in my problem I'm calling named templates instead of applying to the whole document). What I am calling template2 should be applied to the output of the transformation performed by template1.

Should I be declaring variable $vPass2 somewhere within template1 instead of in the same place as where i declare $vPass1? Or is there something else I'm not getting about how this works?

<xsl:template match="/">
  <xsl:variable name="vPass1" >
   <xsl:call-template name="template1"/>
  </xsl:variable>
   <xsl:apply-templates mode="pass2" select="$vPass1/*"/>
  <xsl:variable name="vPass2" >
   <xsl:call-template name="template2"/>
  </xsl:variable>
   <xsl:apply-templates mode="pass3" select="$vPass2/*"/>
 </xsl:template>

Thanks

Kjurdt
  • 37
  • 4

1 Answers1

1

When applying another step - here the third - you have to put the result of the second pass into a variable, too.

So, adding to the example from the linked answer, a three step solution could look like this:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
  <xsl:output omit-xml-declaration="yes" indent="yes" />

  <xsl:template match="/*">
    <xsl:copy>
      <xsl:variable name="vPass1">
        <xsl:apply-templates select="/*/*" />
      </xsl:variable>
      <xsl:variable name="vPass2">
        <xsl:apply-templates mode="pass2" select="$vPass1/*" />
      </xsl:variable>
      <xsl:variable name="vPass3">
        <xsl:apply-templates mode="pass3" select="$vPass2/*" />
      </xsl:variable>
      <!-- Display the final result -->
      <xsl:copy-of select="$vPass3"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="num[. mod 2 = 1]">
    <xsl:copy-of select="."/>
  </xsl:template>

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

  <xsl:template match="num" mode="pass3">
    <xsl:copy>
      <xsl:value-of select=". + 1"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

Applied to this input XML

<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 (2*x+1)

<nums>
   <num>3</num>
   <num>7</num>
   <num>11</num>
   <num>15</num>
   <num>19</num>
</nums>

Relating to your special question, your second <xsl:apply-templates mode="pass2" select="$vPass1/*"/> is not in a variable - so its result will not be passed on to the third step.

zx485
  • 28,498
  • 28
  • 50
  • 59
  • Thank you, that's great. When I have both and the output of both pass2 and pass3 are shown in the final output. What could be causing this? In your example only the output of pass3 is shown... – Kjurdt Feb 21 '19 at 21:14
  • I updated my answer; the reason could be that you grouped the `apply-template`s and the `call-template`s wrong. If you'd have both in one variable, you would end up with a concatenation of both in the next step. – zx485 Feb 21 '19 at 21:29
  • Ah i see, that makes sense. Thanks very much! – Kjurdt Feb 22 '19 at 18:09